mirror of
https://github.com/Sarsoo/csbindgen.git
synced 2024-12-23 06:56:27 +00:00
ready 1.4.0
This commit is contained in:
parent
f163a32e0c
commit
4d900612c8
11
README.md
11
README.md
@ -26,7 +26,7 @@ Install on `Cargo.toml` as `build-dependencies` and set up `bindgen::Builder` on
|
||||
|
||||
```toml
|
||||
[build-dependencies]
|
||||
csbindgen = "1.3.0"
|
||||
csbindgen = "1.4.0"
|
||||
```
|
||||
|
||||
### Rust to C#.
|
||||
@ -192,6 +192,15 @@ namespace {csharp_namespace}
|
||||
|
||||
`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.
|
||||
|
||||
`input_extern_file` allows mulitple call, if you need to add dependent struct, use this.
|
||||
|
||||
```rust
|
||||
csbindgen::Builder::default()
|
||||
.input_extern_file("src/lib.rs")
|
||||
.input_extern_file("src/struct_modules.rs")
|
||||
.generate_csharp_file("../dotnet-sandbox/NativeMethods.cs");
|
||||
```
|
||||
|
||||
### Unity Callback
|
||||
|
||||
`csharp_use_function_pointer` configures how generate function pointer. The default is to generate a `delegate*`, but Unity does not support it; setting it to `false` will generate a `Func/Action` that can be used with `MonoPInvokeCallback`.
|
||||
|
80
csbindgen-tests/build.rs
vendored
80
csbindgen-tests/build.rs
vendored
@ -32,10 +32,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
// .write_to_file("src/quiche.rs")?;
|
||||
|
||||
|
||||
bindgen::Builder::default()
|
||||
.header("c/sqlite3/sqlite3.h")
|
||||
.generate()?
|
||||
.write_to_file("src/sqlite3.rs")?;
|
||||
// bindgen::Builder::default()
|
||||
// .header("c/sqlite3/sqlite3.h")
|
||||
// .generate()?
|
||||
// .write_to_file("src/sqlite3.rs")?;
|
||||
|
||||
// bindgen::Builder::default()
|
||||
// .header("c/bullet3/PhysicsClientC_API.h")
|
||||
@ -66,21 +66,21 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
.unwrap();
|
||||
|
||||
|
||||
csbindgen::Builder::default()
|
||||
.input_bindgen_file("src/sqlite3.rs")
|
||||
.method_filter(|x| x.starts_with("sqlite3_"))
|
||||
.rust_method_prefix("csbindgen_")
|
||||
.rust_file_header("use super::sqlite3::*;")
|
||||
// .rust_method_type_path("sqlite3")
|
||||
.csharp_class_name("LibSqlite3")
|
||||
.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")
|
||||
.generate_to_file("src/sqlite3_ffi.rs", "../dotnet-sandbox/sqlite3_bindgen.cs")
|
||||
.unwrap();
|
||||
// csbindgen::Builder::default()
|
||||
// .input_bindgen_file("src/sqlite3.rs")
|
||||
// .method_filter(|x| x.starts_with("sqlite3_"))
|
||||
// .rust_method_prefix("csbindgen_")
|
||||
// .rust_file_header("use super::sqlite3::*;")
|
||||
// // .rust_method_type_path("sqlite3")
|
||||
// .csharp_class_name("LibSqlite3")
|
||||
// .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")
|
||||
// .generate_to_file("src/sqlite3_ffi.rs", "../dotnet-sandbox/sqlite3_bindgen.cs")
|
||||
// .unwrap();
|
||||
|
||||
csbindgen::Builder::default()
|
||||
.input_extern_file("src/lib.rs")
|
||||
@ -92,29 +92,29 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
.generate_csharp_file("../dotnet-sandbox/NativeMethods.cs")
|
||||
.unwrap();
|
||||
|
||||
csbindgen::Builder::new()
|
||||
.input_bindgen_file("src/zstd.rs")
|
||||
.method_filter(|x| x.starts_with("ZSTD_"))
|
||||
.rust_file_header("use super::zstd::*;")
|
||||
.csharp_class_name("LibZstd")
|
||||
.csharp_dll_name("libzsd")
|
||||
.generate_to_file("src/zstd_ffi.rs", "../dotnet-sandbox/zstd_bindgen.cs")?;
|
||||
// csbindgen::Builder::new()
|
||||
// .input_bindgen_file("src/zstd.rs")
|
||||
// .method_filter(|x| x.starts_with("ZSTD_"))
|
||||
// .rust_file_header("use super::zstd::*;")
|
||||
// .csharp_class_name("LibZstd")
|
||||
// .csharp_dll_name("libzsd")
|
||||
// .generate_to_file("src/zstd_ffi.rs", "../dotnet-sandbox/zstd_bindgen.cs")?;
|
||||
|
||||
csbindgen::Builder::new()
|
||||
.input_bindgen_file("src/quiche.rs")
|
||||
.method_filter(|x| x.starts_with("quiche_"))
|
||||
.rust_file_header("use super::quiche::*;")
|
||||
.csharp_class_name("LibQuiche")
|
||||
.csharp_dll_name("libquiche")
|
||||
.generate_to_file("src/quiche_ffi.rs", "../dotnet-sandbox/quiche_bindgen.cs")?;
|
||||
// csbindgen::Builder::new()
|
||||
// .input_bindgen_file("src/quiche.rs")
|
||||
// .method_filter(|x| x.starts_with("quiche_"))
|
||||
// .rust_file_header("use super::quiche::*;")
|
||||
// .csharp_class_name("LibQuiche")
|
||||
// .csharp_dll_name("libquiche")
|
||||
// .generate_to_file("src/quiche_ffi.rs", "../dotnet-sandbox/quiche_bindgen.cs")?;
|
||||
|
||||
csbindgen::Builder::new()
|
||||
.input_bindgen_file("src/bullet3.rs")
|
||||
.method_filter(|x| x.starts_with("b3"))
|
||||
.rust_file_header("use super::bullet3::*;")
|
||||
.csharp_class_name("LibBullet3")
|
||||
.csharp_dll_name("libbullet3")
|
||||
.generate_to_file("src/bullet3_ffi.rs", "../dotnet-sandbox/bullet3_bindgen.cs")?;
|
||||
// csbindgen::Builder::new()
|
||||
// .input_bindgen_file("src/bullet3.rs")
|
||||
// .method_filter(|x| x.starts_with("b3"))
|
||||
// .rust_file_header("use super::bullet3::*;")
|
||||
// .csharp_class_name("LibBullet3")
|
||||
// .csharp_dll_name("libbullet3")
|
||||
// .generate_to_file("src/bullet3_ffi.rs", "../dotnet-sandbox/bullet3_bindgen.cs")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
45
csbindgen-tests/src/lib.rs
vendored
45
csbindgen-tests/src/lib.rs
vendored
@ -3,8 +3,6 @@ use std::{
|
||||
ffi::{c_char, c_long, c_ulong, c_void, CString},
|
||||
};
|
||||
|
||||
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(non_camel_case_types)]
|
||||
@ -60,31 +58,48 @@ mod lz4_ffi;
|
||||
// #[allow(non_camel_case_types)]
|
||||
// mod zstd_ffi;
|
||||
|
||||
mod others;
|
||||
pub use others::HogeMoge;
|
||||
// mod others;
|
||||
// pub use others::HogeMoge;
|
||||
|
||||
// #[no_mangle]
|
||||
// pub extern "C" fn other_1(hoge: HogeMoge) {
|
||||
// println!("{:?}", hoge);
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
pub struct NfcCard {
|
||||
pub delegate: unsafe extern "C" fn(ByteArray) -> ByteArray
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn other_1(hoge: HogeMoge){
|
||||
println!("{}", hoge);
|
||||
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 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,
|
||||
),
|
||||
>,
|
||||
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)]
|
||||
|
1
csbindgen-tests/src/others.rs
vendored
1
csbindgen-tests/src/others.rs
vendored
@ -6,4 +6,5 @@
|
||||
pub enum HogeMoge{
|
||||
X = 0,
|
||||
Y = 1,
|
||||
event = 2
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "csbindgen"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
edition = "2021"
|
||||
authors = [
|
||||
"Yoshifumi Kawai <ils@neue.cc>",
|
||||
|
@ -107,7 +107,12 @@ pub fn emit_csharp(
|
||||
|
||||
let mut method_list_string = String::new();
|
||||
for item in methods {
|
||||
let method_name = &item.method_name;
|
||||
let mut method_name = &item.method_name;
|
||||
let method_name_temp: String;
|
||||
if method_prefix.is_empty() {
|
||||
method_name_temp = escape_name(method_name);
|
||||
method_name = &method_name_temp;
|
||||
}
|
||||
|
||||
if let Some(x) = &item.return_type {
|
||||
if let Some(delegate_method) = build_method_delegate_if_required(
|
||||
@ -165,7 +170,7 @@ pub fn emit_csharp(
|
||||
type_name = "[MarshalAs(UnmanagedType.U1)] bool".to_string();
|
||||
}
|
||||
|
||||
format!("{} {}", type_name, p.escape_name())
|
||||
format!("{} {}", type_name, escape_name(p.name.as_str()))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
@ -189,7 +194,7 @@ pub fn emit_csharp(
|
||||
|
||||
let mut structs_string = String::new();
|
||||
for item in structs {
|
||||
let name = &item.struct_name;
|
||||
let name = escape_name(&item.struct_name);
|
||||
let layout_kind = if item.is_union {
|
||||
"Explicit"
|
||||
} else {
|
||||
@ -220,7 +225,7 @@ pub fn emit_csharp(
|
||||
};
|
||||
|
||||
structs_string
|
||||
.push_str(format!(" {}public {} {}", attr, type_name, field.name).as_str());
|
||||
.push_str(format!(" {}public {} {}", attr, type_name, escape_name(field.name.as_str())).as_str());
|
||||
if let TypeKind::FixedArray(digits, _) = &field.rust_type.type_kind {
|
||||
let mut digits = digits.clone();
|
||||
if digits == "0" {
|
||||
|
@ -1,31 +1,30 @@
|
||||
use crate::{alias_map::AliasMap, builder::BindgenOptions};
|
||||
|
||||
pub fn escape_name(str: &str) -> String {
|
||||
match str {
|
||||
// C# keywords: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
|
||||
"abstract" | "as" | "base" | "bool" | "break" | "byte" | "case" | "catch" | "char"
|
||||
| "checked" | "class" | "const" | "continue" | "decimal" | "default" | "delegate"
|
||||
| "do" | "double" | "else" | "enum" | "event" | "explicit" | "extern" | "false"
|
||||
| "finally" | "fixed" | "float" | "for" | "foreach" | "goto" | "if" | "implicit" | "in"
|
||||
| "int" | "interface" | "internal" | "is" | "lock" | "long" | "namespace" | "new"
|
||||
| "null" | "object" | "operator" | "out" | "override" | "params" | "private"
|
||||
| "protected" | "public" | "readonly" | "ref" | "return" | "sbyte" | "sealed" | "short"
|
||||
| "sizeof" | "stackalloc" | "static" | "string" | "struct" | "switch" | "this"
|
||||
| "throw" | "true" | "try" | "typeof" | "uint" | "ulong" | "unchecked" | "unsafe"
|
||||
| "ushort" | "using" | "virtual" | "void" | "volatile" | "while" => {
|
||||
"@".to_string() + str
|
||||
}
|
||||
x => x.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Parameter {
|
||||
pub name: String,
|
||||
pub rust_type: RustType,
|
||||
}
|
||||
|
||||
impl Parameter {
|
||||
pub fn escape_name(&self) -> String {
|
||||
match self.name.as_str() {
|
||||
// C# keywords: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
|
||||
"abstract" | "as" | "base" | "bool" | "break" | "byte" | "case" | "catch" | "char"
|
||||
| "checked" | "class" | "const" | "continue" | "decimal" | "default" | "delegate"
|
||||
| "do" | "double" | "else" | "enum" | "event" | "explicit" | "extern" | "false"
|
||||
| "finally" | "fixed" | "float" | "for" | "foreach" | "goto" | "if" | "implicit"
|
||||
| "in" | "int" | "interface" | "internal" | "is" | "lock" | "long" | "namespace"
|
||||
| "new" | "null" | "object" | "operator" | "out" | "override" | "params"
|
||||
| "private" | "protected" | "public" | "readonly" | "ref" | "return" | "sbyte"
|
||||
| "sealed" | "short" | "sizeof" | "stackalloc" | "static" | "string" | "struct"
|
||||
| "switch" | "this" | "throw" | "true" | "try" | "typeof" | "uint" | "ulong"
|
||||
| "unchecked" | "unsafe" | "ushort" | "using" | "virtual" | "void" | "volatile"
|
||||
| "while" => "@".to_string() + self.name.as_str(),
|
||||
x => x.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FieldMember {
|
||||
pub name: String,
|
||||
@ -153,7 +152,7 @@ impl RustType {
|
||||
.map(|x| {
|
||||
format!(
|
||||
"{}: {}",
|
||||
x.escape_name(),
|
||||
escape_name(x.name.as_str()),
|
||||
x.rust_type.to_rust_string(type_path)
|
||||
)
|
||||
})
|
||||
@ -184,7 +183,8 @@ impl RustType {
|
||||
method_name: &String,
|
||||
parameter_name: &String,
|
||||
) -> String {
|
||||
fn convert_type_name(type_name: &str) -> &str {
|
||||
fn convert_type_name(type_name: &str) -> String {
|
||||
let temp_string: String;
|
||||
let name = match type_name {
|
||||
// std::os::raw https://doc.rust-lang.org/std/os/raw/index.html
|
||||
// std::ffi::raw https://doc.rust-lang.org/core/ffi/index.html
|
||||
@ -220,9 +220,12 @@ impl RustType {
|
||||
"bool" => "bool",
|
||||
"usize" => "nuint", // C# 9.0
|
||||
"()" => "void",
|
||||
_ => type_name, // as is
|
||||
_ => {
|
||||
temp_string = escape_name(type_name);
|
||||
temp_string.as_str()
|
||||
}
|
||||
};
|
||||
name
|
||||
name.to_string()
|
||||
}
|
||||
|
||||
// resolve alias
|
||||
@ -233,7 +236,13 @@ impl RustType {
|
||||
|
||||
// if alias if Option, unwrap.
|
||||
let type_csharp_string = if use_alias {
|
||||
use_type.to_csharp_string(options, alias_map, emit_from_struct, method_name, parameter_name)
|
||||
use_type.to_csharp_string(
|
||||
options,
|
||||
alias_map,
|
||||
emit_from_struct,
|
||||
method_name,
|
||||
parameter_name,
|
||||
)
|
||||
} else {
|
||||
convert_type_name(use_type.type_name.as_str()).to_string()
|
||||
};
|
||||
@ -421,7 +430,7 @@ pub fn build_method_delegate_if_required(
|
||||
method_name,
|
||||
parameter_name,
|
||||
);
|
||||
format!("{} {}", cs, p.escape_name())
|
||||
format!("{} {}", cs, escape_name(p.name.as_str()))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
31
dotnet-sandbox/NativeMethods.cs
vendored
31
dotnet-sandbox/NativeMethods.cs
vendored
@ -12,8 +12,11 @@ namespace CsBindgen
|
||||
{
|
||||
const string __DllName = "csbindgen_tests";
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "other_1", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void other_1(HogeMoge hoge);
|
||||
[DllImport(__DllName, EntryPoint = "other_2", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void other_2(NfcCard _hoge);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "@event", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void @event(@event @event);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "nest_test", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void nest_test(delegate* unmanaged[Cdecl]<delegate* unmanaged[Cdecl]<int, void>*, int> _f);
|
||||
@ -130,6 +133,24 @@ namespace CsBindgen
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct NfcCard
|
||||
{
|
||||
public delegate* unmanaged[Cdecl]<ByteArray, ByteArray> @delegate;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct ByteArray
|
||||
{
|
||||
public int i;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct @event
|
||||
{
|
||||
public int a;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal unsafe partial struct MyUnion
|
||||
{
|
||||
@ -176,12 +197,6 @@ namespace CsBindgen
|
||||
C = 10,
|
||||
}
|
||||
|
||||
internal enum HogeMoge : int
|
||||
{
|
||||
X = 0,
|
||||
Y = 1,
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user