diff --git a/csbindgen-tests/build.rs b/csbindgen-tests/build.rs index 3144313..2af8b24 100644 --- a/csbindgen-tests/build.rs +++ b/csbindgen-tests/build.rs @@ -2,15 +2,15 @@ // fn main() -> Result<(), Box> { fn main() { - bindgen::Builder::default() - .header("c/lz4/lz4.h") - .header("c/lz4/lz4hc.h") - .header("c/lz4/lz4frame.h") - .header("c/lz4/xxhash.h") - .generate() - .unwrap() - .write_to_file("src/lz4.rs") - .unwrap(); + // bindgen::Builder::default() + // .header("c/lz4/lz4.h") + // .header("c/lz4/lz4hc.h") + // .header("c/lz4/lz4frame.h") + // .header("c/lz4/xxhash.h") + // .generate() + // .unwrap() + // .write_to_file("src/lz4.rs") + // .unwrap(); cc::Build::new() .files([ @@ -40,23 +40,23 @@ fn main() { // .generate()? // .write_to_file("src/bullet3.rs")?; - csbindgen::Builder::default() - .input_bindgen_file("src/lz4.rs") - .method_filter(|x| { !x.starts_with("_") && !x.starts_with("XXH") } ) - .rust_method_prefix("csbindgen_") - .rust_file_header("use super::lz4;") - .rust_method_type_path("lz4") - .csharp_class_name("LibLz4") - .csharp_namespace("CsBindgen") - .csharp_dll_name("csbindgen_tests") - .csharp_dll_name_if("UNITY_IOS && !UNITY_EDITOR", "__Internal") - .csharp_entry_point_prefix("csbindgen_") - .csharp_method_prefix("") - .csharp_class_accessibility("public") - .csharp_c_long_convert("int") - .csharp_c_ulong_convert("uint") - .generate_to_file("src/lz4_ffi.rs", "../dotnet-sandbox/lz4_bindgen.cs") - .unwrap(); + // csbindgen::Builder::default() + // .input_bindgen_file("src/lz4.rs") + // .method_filter(|x| { !x.starts_with("_") && !x.starts_with("XXH") } ) + // .rust_method_prefix("csbindgen_") + // .rust_file_header("use super::lz4;") + // .rust_method_type_path("lz4") + // .csharp_class_name("LibLz4") + // .csharp_namespace("CsBindgen") + // .csharp_dll_name("csbindgen_tests") + // .csharp_dll_name_if("UNITY_IOS && !UNITY_EDITOR", "__Internal") + // .csharp_entry_point_prefix("csbindgen_") + // .csharp_method_prefix("") + // .csharp_class_accessibility("public") + // .csharp_c_long_convert("int") + // .csharp_c_ulong_convert("uint") + // .generate_to_file("src/lz4_ffi.rs", "../dotnet-sandbox/lz4_bindgen.cs") + // .unwrap(); csbindgen::Builder::default() .input_extern_file("src/lib.rs") diff --git a/csbindgen-tests/src/lib.rs b/csbindgen-tests/src/lib.rs index f56b4d6..afda906 100644 --- a/csbindgen-tests/src/lib.rs +++ b/csbindgen-tests/src/lib.rs @@ -14,6 +14,17 @@ pub extern "C" fn my_add(x: i32, y: i32) -> i32 { x + y } +#[allow(unused)] +#[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 + } +} + #[test] fn build_test() { // let path = std::env::current_dir().unwrap(); diff --git a/csbindgen/src/emitter.rs b/csbindgen/src/emitter.rs index 8c7af83..b5f2015 100644 --- a/csbindgen/src/emitter.rs +++ b/csbindgen/src/emitter.rs @@ -9,7 +9,7 @@ pub fn emit_rust_method(list: &Vec, options: &BindgenOptions) -> S let method_type_path = options.rust_method_type_path.as_str(); let method_type_path2 = match options.rust_method_type_path.as_str() { "" => "".to_string(), - x => x.to_string() + "::" + x => x.to_string() + "::", }; let method_prefix = &options.rust_method_prefix; let file_header = &options.rust_file_header; @@ -81,7 +81,7 @@ pub fn emit_csharp( methods: &Vec, aliases: &HashMap, structs: &Vec, - options: &BindgenOptions + options: &BindgenOptions, ) -> String { // configure let namespace = &options.csharp_namespace; @@ -90,13 +90,20 @@ pub fn emit_csharp( let accessibility = &options.csharp_class_accessibility; let dll_name = match options.csharp_if_symbol.as_str() { - "" => format!(" const string __DllName = \"{}\";", options.csharp_dll_name), - _ => { format!("#if {0} + "" => format!( + " const string __DllName = \"{}\";", + options.csharp_dll_name + ), + _ => { + format!( + "#if {0} const string __DllName = \"{1}\"; #else const string __DllName = \"{2}\"; #endif - ", options.csharp_if_symbol, options.csharp_if_dll_name, options.csharp_dll_name) + ", + options.csharp_if_symbol, options.csharp_if_dll_name, options.csharp_dll_name + ) } }; @@ -104,8 +111,8 @@ pub fn emit_csharp( for item in methods { let method_name = &item.method_name; let entry_point = match options.csharp_entry_point_prefix.as_str() { - "" => format!("{method_prefix}{method_name}"), - x => format!("{x}{method_name}"), + "" => format!("{method_prefix}{method_name}"), + x => format!("{x}{method_name}"), }; let return_type = match &item.return_type { Some(x) => x.to_csharp_string(options, aliases), @@ -115,13 +122,23 @@ pub fn emit_csharp( let parameters = item .parameters .iter() - .map(|p| format!("{} {}", p.rust_type.to_csharp_string(options, aliases), p.escape_name())) + .map(|p| { + let mut type_name = p.rust_type.to_csharp_string(options, aliases); + if type_name == "bool" { + type_name = "[MarshalAs(UnmanagedType.U1)] bool".to_string(); + } + + format!("{} {}", type_name, p.escape_name()) + }) .collect::>() .join(", "); method_list_string.push_str_ln( format!(" [DllImport(__DllName, EntryPoint = \"{entry_point}\", CallingConvention = CallingConvention.Cdecl)]").as_str(), ); + if return_type == "bool" { + method_list_string.push_str_ln(" [return: MarshalAs(UnmanagedType.U1)]"); + } method_list_string.push_str_ln( format!(" public static extern {return_type} {method_prefix}{method_name}({parameters});").as_str(), ); diff --git a/dotnet-sandbox/Program.cs b/dotnet-sandbox/Program.cs index 4f681ab..9da0d70 100644 --- a/dotnet-sandbox/Program.cs +++ b/dotnet-sandbox/Program.cs @@ -6,79 +6,31 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; unsafe { - //var v = NativeMethods(); + var a = false; + var b = false; + var c = false; - var z = LibRust.my_add(100, 200); + + + var z = LibRust.my_bool(true, false, true, &a, &b, &c); + + + Console.WriteLine(a); + Console.WriteLine(b); + Console.WriteLine(c); Console.WriteLine(z); - var s = CsBindgen.LibLz4.LZ4_versionString(); - var ss = new string((sbyte*)s); - Console.WriteLine(ss); - - //var bytes = new byte[] { 1, 10, 100, 100, 100, 100, 100, 100 }; - //var dest = new byte[100]; - - //fixed (byte* p = bytes) - //fixed (byte* d = dest) - //{ - - // var len = NativeMethods.csbindgen_LZ4_compress_default(p, d, bytes.Length, dest.Length); - - //} - - - // var vvv = new string((sbyte*)v); - - // Console.WriteLine(vvv); - } + +public static unsafe partial class LibraryImportNativeMethods { - public static unsafe partial class LibLz4 - { - static LibLz4() - { - NativeLibrary.SetDllImportResolver(typeof(LibLz4).Assembly, DllImportResolver); - } + const string __DllName = "csbindgen_tests"; - static IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) - { - if (libraryName == __DllName) - { - var path = "runtimes/"; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - path += "win-"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - path += "osx-"; - } - else - { - path += "linux-"; - } + [LibraryImport(__DllName, EntryPoint = "my_bool")] + [return: MarshalAs(UnmanagedType.U1)] + public static partial bool my_bool([MarshalAs(UnmanagedType.U1)] bool x, [MarshalAs(UnmanagedType.U1)] bool y, [MarshalAs(UnmanagedType.U1)] bool z, bool* xr, bool* yr, bool* zr); - if (RuntimeInformation.OSArchitecture == Architecture.X86) - { - path += "x86"; - } - else if (RuntimeInformation.OSArchitecture == Architecture.X64) - { - path += "x64"; - } - else if (RuntimeInformation.OSArchitecture == Architecture.Arm64) - { - path += "arm64"; - } - path += "/native/" + __DllName; - - return NativeLibrary.Load(path, assembly, searchPath); - } - - return IntPtr.Zero; - } - } } \ No newline at end of file diff --git a/dotnet-sandbox/method_call.cs b/dotnet-sandbox/method_call.cs index af21cb2..b5140e2 100644 --- a/dotnet-sandbox/method_call.cs +++ b/dotnet-sandbox/method_call.cs @@ -14,6 +14,10 @@ namespace CsBindgen [DllImport(__DllName, EntryPoint = "my_add", CallingConvention = CallingConvention.Cdecl)] public static extern int my_add(int x, int y); + [DllImport(__DllName, EntryPoint = "my_bool", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool my_bool([MarshalAs(UnmanagedType.U1)] bool x, [MarshalAs(UnmanagedType.U1)] bool y, [MarshalAs(UnmanagedType.U1)] bool z, bool* xr, bool* yr, bool* zr); + }