mirror of
https://github.com/Sarsoo/csbindgen.git
synced 2025-01-09 21:37:46 +00:00
685 lines
17 KiB
Rust
Vendored
685 lines
17 KiB
Rust
Vendored
use std::{
|
|
collections::HashSet,
|
|
ffi::{c_char, c_long, c_ulong, CString},
|
|
num::*,
|
|
ptr::NonNull,
|
|
};
|
|
|
|
#[allow(dead_code)]
|
|
#[allow(non_snake_case)]
|
|
#[allow(non_camel_case_types)]
|
|
#[allow(non_upper_case_globals)]
|
|
mod lz4;
|
|
|
|
#[allow(dead_code)]
|
|
#[allow(non_snake_case)]
|
|
#[allow(non_camel_case_types)]
|
|
mod lz4_ffi;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// #[allow(non_upper_case_globals)]
|
|
// mod sqlite3;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// mod sqlite3_ffi;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// #[allow(non_upper_case_globals)]
|
|
// mod bullet3;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// mod bullet3_ffi;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// #[allow(non_upper_case_globals)]
|
|
// mod quiche;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// mod quiche_ffi;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// #[allow(non_upper_case_globals)]
|
|
// mod zstd;
|
|
|
|
// #[allow(dead_code)]
|
|
// #[allow(non_snake_case)]
|
|
// #[allow(non_camel_case_types)]
|
|
// mod zstd_ffi;
|
|
|
|
// mod others;
|
|
// pub use others::HogeMoge;
|
|
|
|
// #[no_mangle]
|
|
// pub extern "C" fn other_1(hoge: HogeMoge) {
|
|
// println!("{:?}", hoge);
|
|
// }
|
|
|
|
// #[no_mangle]
|
|
// pub extern "C" fn string_char(str: char) {
|
|
// println!("{}", str);
|
|
// }
|
|
|
|
#[allow(non_camel_case_types)]
|
|
pub type png_byte = ::std::os::raw::c_uchar;
|
|
|
|
#[allow(non_camel_case_types)]
|
|
pub type JPH_ContactPoints = [u128; 65usize];
|
|
#[allow(non_camel_case_types)]
|
|
pub type JPH_ContactPoints2 = [u128; 65];
|
|
|
|
#[repr(C)]
|
|
#[allow(unused)]
|
|
#[allow(non_snake_case)]
|
|
pub struct JPH_ContactManifold {
|
|
pub mPenetrationDepth: f32,
|
|
pub mWorldSpaceContactPointsOn1: JPH_ContactPoints,
|
|
pub mWorldSpaceContactPointsOn2: JPH_ContactPoints,
|
|
pub mWorldSpaceContactPointsOn3: JPH_ContactPoints2,
|
|
pub mWorldSpaceContactPointsOn4: [u128; 65],
|
|
pub mWorldSpaceContactPointsOn5: [u32; 65],
|
|
pub png_name: [png_byte; 5usize],
|
|
}
|
|
|
|
#[no_mangle]
|
|
#[allow(unused)]
|
|
#[allow(non_snake_case)]
|
|
pub extern "C" fn JPH_PruneContactPoints(
|
|
ioContactPointsOn1: *mut JPH_ContactPoints,
|
|
ioContactPointsOn2: *mut JPH_ContactManifold,
|
|
) {
|
|
todo!();
|
|
}
|
|
|
|
use bitflags::bitflags;
|
|
|
|
bitflags! {
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
struct EnumFlags: u32 {
|
|
const A = 0b00000001;
|
|
const B = 0b00000010;
|
|
const C = 0b00000100;
|
|
const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits();
|
|
}
|
|
}
|
|
|
|
pub const FOO: i32 = 10;
|
|
pub const BAR: f32 = 120.432;
|
|
pub const BAR32: f32 = 120.431;
|
|
pub const BAR64: f64 = 120.432;
|
|
pub const STR: &str = "aiueo3";
|
|
pub const BSTR: &[u8] = b"kakikukeko"; // currently not supported.
|
|
pub const CBYTE: u8 = b'A';
|
|
pub const CCHAR: char = 'あ';
|
|
pub const BOOLCONST_T: bool = true;
|
|
pub const BOOLCONST_F: bool = false;
|
|
|
|
/// my comment!
|
|
#[no_mangle]
|
|
extern "C" fn comment_one(_flags: EnumFlags) {}
|
|
|
|
/// Multiline Comments
|
|
/// # GOTO
|
|
/// Here
|
|
/// Foo
|
|
/// Bar
|
|
///
|
|
/// TO
|
|
///
|
|
/// ZZZ
|
|
pub extern "C" fn long_jpn_comment() {}
|
|
|
|
#[repr(C)]
|
|
pub struct my_int_vec3(i32, i32, i32);
|
|
|
|
pub extern "C" fn use_vec3(_v3: my_int_vec3) {}
|
|
|
|
#[repr(C)]
|
|
pub struct NfcCard {
|
|
pub delegate: unsafe extern "C" fn(ByteArray) -> ByteArray,
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn other_2(_hoge: NfcCard) {}
|
|
|
|
#[repr(C)]
|
|
pub struct ByteArray {
|
|
pub i: i32,
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub struct event {
|
|
pub a: i32,
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn event(event: event) {
|
|
println!("{:?}", event);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn test_func_issue_39(_f: extern "C" fn(i32)) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn test_func_issue_39_variation1(_f: extern "C" fn(i32, i32, i32)) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn nonnull_parameter(_output_word_uuid: NonNull<[u8; 16]>) {}
|
|
|
|
// #[no_mangle]
|
|
// pub extern "C" fn non_nonnull_parameter(_output_word_uuid: [u8; 16]){
|
|
// }
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn non_nonnull_parameter2(_output_word_uuid: NonNull<u8>) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn nonzero_test(_a: NonZeroI8, _b: NonZeroU8, _c: NonZeroU32) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn ge(_f: extern "C" fn(i32, i32, i32)) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn nest_test(
|
|
_f: ::std::option::Option<
|
|
unsafe extern "C" fn(
|
|
pxFunc: *mut ::std::option::Option<unsafe extern "C" fn(arg2: ::std::os::raw::c_int)>,
|
|
) -> ::std::os::raw::c_int,
|
|
>,
|
|
) {
|
|
}
|
|
|
|
#[allow(non_camel_case_types)]
|
|
pub type LONG_PTR = ::std::os::raw::c_longlong;
|
|
#[allow(non_camel_case_types)]
|
|
pub type PSSIZE_T = *mut LONG_PTR;
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn alias_test1(_a: PSSIZE_T) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn alias_test2(_b: LONG_PTR) {}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn nullpointer_test(p: *const u8) {
|
|
let ptr = unsafe { p.as_ref() };
|
|
match ptr {
|
|
Some(p2) => print!("pointer address: {}", *p2),
|
|
None => println!("null pointer!"),
|
|
};
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn csharp_to_rust_string(utf16_str: *const u16, utf16_len: i32) {
|
|
let slice = std::slice::from_raw_parts(utf16_str, utf16_len as usize);
|
|
|
|
let str = String::from_utf16(slice).unwrap();
|
|
|
|
println!("{}", str);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn csharp_to_rust_utf8(utf8_str: *const u8, utf8_len: i32) {
|
|
let slice = std::slice::from_raw_parts(utf8_str, utf8_len as usize);
|
|
let str = String::from_utf8_unchecked(slice.to_vec());
|
|
println!("{}", str);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn csharp_to_rust_bytes(bytes: *const u8, len: i32) {
|
|
let slice = std::slice::from_raw_parts(bytes, len as usize);
|
|
let vec = slice.to_vec();
|
|
println!("{:?}", vec);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn callback_test(cb: extern "C" fn(a: i32) -> i32) -> i32 {
|
|
cb(100)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn csharp_to_rust(cb: extern "C" fn(x: i32, y: i32) -> i32) {
|
|
let sum = cb(10, 20); // invoke C# method
|
|
println!("{sum}");
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn rust_to_csharp() -> extern "C" fn(x: i32, y: i32) -> i32 {
|
|
sum // return rust method
|
|
}
|
|
|
|
extern "C" fn sum(x: i32, y: i32) -> i32 {
|
|
x + y
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn cbt(_cb: CallbackTable) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn nullable_callback_test(cb: Option<extern "C" fn(a: i32) -> i32>) -> i32 {
|
|
match cb {
|
|
Some(f) => f(100),
|
|
None => -1,
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn types_iroiro(_i: isize, _u: usize, _cl: c_long, _cul: c_ulong) {}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn callback_test2() -> extern "C" fn(a: i32) -> i32 {
|
|
callback
|
|
}
|
|
|
|
extern "C" fn callback(a: i32) -> i32 {
|
|
a * a
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn enum_test(i: IntEnumTest) -> i32 {
|
|
i as i32
|
|
}
|
|
|
|
#[repr(i8)]
|
|
pub enum IntEnumTest {
|
|
A = 1,
|
|
B = 2,
|
|
C = 10,
|
|
}
|
|
|
|
#[no_mangle]
|
|
#[allow(improper_ctypes_definitions)]
|
|
pub extern "C" fn ignore_nop() -> (i32, i32) {
|
|
println!("hello ignore!");
|
|
(1, 2)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn nop() -> () {
|
|
println!("hello nop!");
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn my_add(x: i32, y: i32) -> i32 {
|
|
x + y
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct CounterContext;
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn create_counter_context() -> *mut CounterContext {
|
|
let ctx = Box::new(InternalCounterContext {
|
|
set: HashSet::new(),
|
|
});
|
|
Box::into_raw(ctx) as *mut CounterContext
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn counter_context_insert(context: *mut CounterContext, value: i32) {
|
|
let mut counter = Box::from_raw(context as *mut InternalCounterContext);
|
|
counter.set.insert(value);
|
|
Box::into_raw(counter);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn destroy_counter_context(context: *mut CounterContext) {
|
|
_ = Box::from_raw(context as *mut InternalCounterContext);
|
|
// for value in counter.set.iter() {
|
|
// println!("counter value: {}", value)
|
|
// }
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn pass_vector3(v3: MyVector3) {
|
|
println!("{}, {}, {}", v3.x, v3.y, v3.z);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn return_union() -> MyUnion {
|
|
MyUnion { bar: 53 }
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub union MyUnion {
|
|
pub foo: i32,
|
|
pub bar: i64,
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct MyVector3 {
|
|
pub x: f32,
|
|
pub y: f32,
|
|
pub z: f32,
|
|
}
|
|
|
|
// not repr(C)
|
|
pub struct InternalCounterContext {
|
|
pub set: HashSet<i32>,
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn my_bool(
|
|
x: bool,
|
|
y: bool,
|
|
z: bool,
|
|
xr: *mut bool,
|
|
yr: *mut bool,
|
|
zr: *mut bool,
|
|
) -> bool {
|
|
unsafe {
|
|
*xr = x;
|
|
*yr = y;
|
|
*zr = z;
|
|
}
|
|
|
|
true
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn alloc_c_string() -> *mut c_char {
|
|
let str = CString::new("foo bar baz").unwrap();
|
|
str.into_raw()
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn free_c_string(str: *mut c_char) {
|
|
unsafe { CString::from_raw(str) };
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn alloc_u8_string() -> *mut ByteBuffer {
|
|
let str = format!("foo bar baz");
|
|
let buf = ByteBuffer::from_vec(str.into_bytes());
|
|
Box::into_raw(Box::new(buf))
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn free_u8_string(buffer: *mut ByteBuffer) {
|
|
let buf = Box::from_raw(buffer);
|
|
// drop inner buffer, if you need String, use String::from_utf8_unchecked(buf.destroy_into_vec()) instead.
|
|
buf.destroy();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn alloc_u8_buffer() -> *mut ByteBuffer {
|
|
let vec: Vec<u8> = vec![1, 10, 100];
|
|
let buf = ByteBuffer::from_vec(vec);
|
|
Box::into_raw(Box::new(buf))
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn free_u8_buffer(buffer: *mut ByteBuffer) {
|
|
let buf = Box::from_raw(buffer);
|
|
// drop inner buffer, if you need Vec<u8>, use buf.destroy_into_vec() instead.
|
|
buf.destroy();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn alloc_i32_buffer() -> *mut ByteBuffer {
|
|
let vec: Vec<i32> = vec![1, 10, 100, 1000, 10000];
|
|
let buf = ByteBuffer::from_vec_struct(vec);
|
|
Box::into_raw(Box::new(buf))
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn free_i32_buffer(buffer: *mut ByteBuffer) {
|
|
let buf = Box::from_raw(buffer);
|
|
// drop inner buffer, if you need Vec<i32>, use buf.destroy_into_vec_struct::<i32>() instead.
|
|
buf.destroy();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn create_context() -> *mut Context {
|
|
let ctx = Box::new(Context { foo: true });
|
|
Box::into_raw(ctx)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn delete_context(context: *mut Context) {
|
|
unsafe { Box::from_raw(context) };
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn call_bindgen() {
|
|
let path = std::env::current_dir().unwrap();
|
|
println!("starting dir: {}", path.display()); // csbindgen/csbindgen-tests
|
|
|
|
csbindgen::Builder::default()
|
|
.input_extern_file("../../../../csbindgen-tests/src/lib.rs")
|
|
.csharp_class_name("LibRust")
|
|
.csharp_dll_name("csbindgen_tests")
|
|
.generate_csharp_file("../../../../dotnet-sandbox/method_call.cs")
|
|
.unwrap();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn call_bindgen_lz4() {
|
|
let path = std::env::current_dir().unwrap();
|
|
println!("starting dir: {}", path.display()); // csbindgen/csbindgen-tests
|
|
|
|
csbindgen::Builder::default()
|
|
.input_bindgen_file("../../../../csbindgen-tests/src/lz4.rs")
|
|
.method_filter(|x| x.starts_with("LZ4"))
|
|
.rust_method_prefix("csbindgen_")
|
|
.rust_file_header("use super::lz4;")
|
|
.rust_method_type_path("lz4")
|
|
.csharp_class_name("LibLz4")
|
|
.csharp_dll_name("csbindgen_tests")
|
|
.generate_to_file(
|
|
"../../../../csbindgen-tests/src/lz4_ffi.cs",
|
|
"../../../../dotnet-sandbox/lz4_bindgen.cs",
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub struct Context {
|
|
pub foo: bool,
|
|
}
|
|
|
|
#[test]
|
|
fn build_test() {
|
|
let path = std::env::current_dir().unwrap();
|
|
println!("starting dir: {}", path.display()); // csbindgen/csbindgen-tests
|
|
std::env::set_current_dir(path.parent().unwrap()).unwrap();
|
|
|
|
// // unsafe {
|
|
// // let num = lz4::LZ4_versionNumber();
|
|
// // println!("lz4 num: {}", num);
|
|
// // }
|
|
|
|
// csbindgen::Builder::default()
|
|
// .input_extern_file("csbindgen-tests/src/lib.rs")
|
|
// .csharp_class_name("NativeMethods")
|
|
// .csharp_dll_name("csbindgen_tests")
|
|
// .generate_csharp_file("dotnet-sandbox/NativeMethods.cs")
|
|
// .unwrap();
|
|
|
|
csbindgen::Builder::new()
|
|
.input_bindgen_file("csbindgen-tests/src/physx/physx_generated.rs")
|
|
.input_bindgen_file("csbindgen-tests/src/physx/x86_64-pc-windows-msvc/structgen.rs")
|
|
.csharp_namespace("Physx")
|
|
.csharp_class_name("LibPhysxd")
|
|
.csharp_dll_name("libphysx")
|
|
.generate_csharp_file("dotnet-sandbox/libphysx_csbindgen.cs")
|
|
.unwrap();
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct ByteBuffer {
|
|
ptr: *mut u8,
|
|
length: i32,
|
|
capacity: i32,
|
|
}
|
|
|
|
impl ByteBuffer {
|
|
pub fn len(&self) -> usize {
|
|
self.length
|
|
.try_into()
|
|
.expect("buffer length negative or overflowed")
|
|
}
|
|
|
|
pub fn from_vec(bytes: Vec<u8>) -> Self {
|
|
let length = i32::try_from(bytes.len()).expect("buffer length cannot fit into a i32.");
|
|
let capacity =
|
|
i32::try_from(bytes.capacity()).expect("buffer capacity cannot fit into a i32.");
|
|
|
|
// keep memory until call delete
|
|
let mut v = std::mem::ManuallyDrop::new(bytes);
|
|
|
|
Self {
|
|
ptr: v.as_mut_ptr(),
|
|
length,
|
|
capacity,
|
|
}
|
|
}
|
|
|
|
pub fn from_vec_struct<T: Sized>(bytes: Vec<T>) -> Self {
|
|
let element_size = std::mem::size_of::<T>() as i32;
|
|
|
|
let length = (bytes.len() as i32) * element_size;
|
|
let capacity = (bytes.capacity() as i32) * element_size;
|
|
|
|
let mut v = std::mem::ManuallyDrop::new(bytes);
|
|
|
|
Self {
|
|
ptr: v.as_mut_ptr() as *mut u8,
|
|
length,
|
|
capacity,
|
|
}
|
|
}
|
|
|
|
pub fn destroy_into_vec(self) -> Vec<u8> {
|
|
if self.ptr.is_null() {
|
|
vec![]
|
|
} else {
|
|
let capacity: usize = self
|
|
.capacity
|
|
.try_into()
|
|
.expect("buffer capacity negative or overflowed");
|
|
let length: usize = self
|
|
.length
|
|
.try_into()
|
|
.expect("buffer length negative or overflowed");
|
|
|
|
unsafe { Vec::from_raw_parts(self.ptr, length, capacity) }
|
|
}
|
|
}
|
|
|
|
pub fn destroy_into_vec_struct<T: Sized>(self) -> Vec<T> {
|
|
if self.ptr.is_null() {
|
|
vec![]
|
|
} else {
|
|
let element_size = std::mem::size_of::<T>() as i32;
|
|
let length = (self.length * element_size) as usize;
|
|
let capacity = (self.capacity * element_size) as usize;
|
|
|
|
unsafe { Vec::from_raw_parts(self.ptr as *mut T, length, capacity) }
|
|
}
|
|
}
|
|
|
|
pub fn destroy(self) {
|
|
drop(self.destroy_into_vec());
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct CallbackTable {
|
|
pub foo: extern "C" fn(),
|
|
pub foobar: extern "C" fn(i: i32) -> i32,
|
|
}
|
|
|
|
|
|
pub extern "C" fn reference_type(_a: &i32, _b: &*mut i32, _c: &[u8; 16], _d: &Context) {}
|
|
|
|
pub extern "C" fn reference_hogemoge1(_a : &mut i32, _b: &&i32){}
|
|
pub extern "C" fn reference_hogemoge2(_a : &mut i32, _b: &*mut i32){}
|
|
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn create_counter_context2() -> *mut CounterContext2 {
|
|
let ctx = Box::new(CounterContext2 {
|
|
set: HashSet::new(),
|
|
});
|
|
Box::into_raw(ctx)
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn insert_counter_context2(context: *mut CounterContext2, value: i32) {
|
|
let mut counter = Box::from_raw(context);
|
|
counter.set.insert(value);
|
|
Box::into_raw(counter);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn delete_counter_context2(context: *mut CounterContext2) {
|
|
let counter = Box::from_raw(context);
|
|
for value in counter.set.iter() {
|
|
println!("counter value: {}", value)
|
|
}
|
|
}
|
|
|
|
// no repr(C)
|
|
pub struct CounterContext2 {
|
|
pub set: HashSet<i32>,
|
|
}
|
|
|
|
pub struct InternalHiddenContext {
|
|
pub a: i32
|
|
}
|
|
|
|
pub struct TreatAsEmptyStruct {
|
|
internal: std::sync::Arc<InternalHiddenContext>
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn init_treat_as_empty_struct_context(_out: NonNull<Box<TreatAsEmptyStruct>>) {}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn free_treat_as_empty_struct_context(_src: *mut TreatAsEmptyStruct) {}
|
|
|
|
|
|
// fn run_physix(){
|
|
// unsafe {
|
|
// let foundation = physx_create_foundation();
|
|
// let physics = physx_create_physics(foundation);
|
|
|
|
// let mut scene_desc = PxSceneDesc_new(PxPhysics_getTolerancesScale(physics));
|
|
// scene_desc.gravity = PxVec3 {
|
|
// x: 0.0,
|
|
// y: -9.81,
|
|
// z: 0.0,
|
|
// };
|
|
|
|
// let dispatcher = phys_PxDefaultCpuDispatcherCreate(
|
|
// 1,
|
|
// null_mut(),
|
|
// PxDefaultCpuDispatcherWaitForWorkMode::WaitForWork,
|
|
// 0,
|
|
// );
|
|
// scene_desc.cpuDispatcher = dispatcher.cast();
|
|
// scene_desc.filterShader = get_default_simulation_filter_shader();
|
|
|
|
// let scene = PxPhysics_createScene_mut(physics, &scene_desc);
|
|
|
|
// // Your physics simulation goes here
|
|
// }
|
|
// }
|