diff --git a/README.md b/README.md index 7e205b9..3f438d6 100644 --- a/README.md +++ b/README.md @@ -154,11 +154,13 @@ csbindgen::Builder::default() .csharp_entry_point_prefix("csbindgen_") .csharp_method_prefix("") .csharp_c_long_convert("int") - .csharp_c_long_convert("uint") + .csharp_c_ulong_convert("uint") .generate_to_file("src/lz4_ffi.rs", "../dotnet-sandbox/lz4_bindgen.cs") .unwrap(); ``` +It will be embedded in the placeholder of the output file. + ```rust #[allow(unused)] use ::std::os::raw::*; @@ -194,19 +196,88 @@ namespace {csharp_namespace} } ``` -Builder options: Rust to C# ---- +Adjust `rust_file_header` and `rust_method_type_path` to match your module configuration. - csbindgen::Builder::default() - .input_extern_file("src/lib.rs") - .csharp_class_name("LibRust") - .csharp_dll_name("csbindgen_tests") - .generate_csharp_file("../dotnet-sandbox/method_call.cs") - .unwrap(); +`method_filter` allows you to specify which methods to exclude; if unspecified, methods prefixed with `_` are excluded by default. +`rust_method_prefix` and `csharp_method_prefix` or `csharp_entry_point_prefix` must be adjusted to match the method name to be called. +`csharp_dll_name_if` is optional. If specified, `#if` allows two DllName to be specified, which is useful if the name must be `__Internal` at iOS build. +If the file path to be loaded needs to be changed depending on the operating system, the following load code can be used. +```csharp +public static unsafe partial class NativeMethods +{ + // https://docs.microsoft.com/en-us/dotnet/standard/native-interop/cross-platform + // Library path will search + // win => __DllName, __DllName.dll + // linux, osx => __DllName.so, __DllName.dylib + // __DllName + + static NativeMethods() + { + NativeLibrary.SetDllImportResolver(typeof(NativeMethods).Assembly, DllImportResolver); + } + + 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-"; + } + + 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; + } +} +``` + +`csharp_c_long_convert` and `csharp_c_ulong_convert` configure how handles `c_long` and `c_ulong` to C# type. default is to `int` and `uint` because `LLP64` is 32bit representation but you can change it to 64bit. + +## Builder options: Rust to C# + +Rust to C# is similar workflow as C to C#, use the `input_extern_file` -> setup options -> `generate_csharp_file`. + +```csharp +csbindgen::Builder::default() + .input_extern_file("src/lib.rs") + .csharp_class_name("LibRust") + .csharp_dll_name("csbindgen_tests") + .generate_csharp_file("../dotnet-sandbox/NativeMethods.cs") + .unwrap(); +``` + +`generate_csharp_file` does not generate Rust file so no need to use `rust_` option. License --- diff --git a/csbindgen-tests/build.rs b/csbindgen-tests/build.rs index b3dc7bf..708ed4c 100644 --- a/csbindgen-tests/build.rs +++ b/csbindgen-tests/build.rs @@ -53,7 +53,7 @@ fn main() { .csharp_entry_point_prefix("csbindgen_") .csharp_method_prefix("") .csharp_c_long_convert("int") - .csharp_c_long_convert("uint") + .csharp_c_ulong_convert("uint") .generate_to_file("src/lz4_ffi.rs", "../dotnet-sandbox/lz4_bindgen.cs") .unwrap(); diff --git a/csbindgen/Cargo.toml b/csbindgen/Cargo.toml index 38ba7da..0472631 100644 --- a/csbindgen/Cargo.toml +++ b/csbindgen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "csbindgen" -version = "0.1.0" +version = "0.1.1" edition = "2021" authors = [ "Yoshifumi Kawai ", diff --git a/csbindgen/src/builder.rs b/csbindgen/src/builder.rs index b77f82d..e0b5c78 100644 --- a/csbindgen/src/builder.rs +++ b/csbindgen/src/builder.rs @@ -142,7 +142,7 @@ impl Builder { self } - /// configure c_long to {csharp_c_long_convert} type, + /// configure c_ulong to {csharp_c_ulong_convert} type, /// default is `uint`. pub fn csharp_c_ulong_convert>(mut self, csharp_c_ulong_convert: T) -> Builder { self.options.csharp_c_ulong_convert = csharp_c_ulong_convert.into(); diff --git a/dotnet-sandbox/Program.cs b/dotnet-sandbox/Program.cs index 95ed354..2aee533 100644 --- a/dotnet-sandbox/Program.cs +++ b/dotnet-sandbox/Program.cs @@ -1,6 +1,7 @@ // See https://aka.ms/new-console-template for more information //using Csbindgen; using CsBindgen; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; unsafe @@ -31,3 +32,54 @@ unsafe // Console.WriteLine(vvv); } + +namespace CsBindgen +{ + public static unsafe partial class LibLz4 + { + static LibLz4() + { + NativeLibrary.SetDllImportResolver(typeof(LibLz4).Assembly, DllImportResolver); + } + + 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-"; + } + + 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