Skip to content

Commit

Permalink
ready 1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Mar 17, 2023
1 parent f163a32 commit 4d90061
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 95 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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#.
Expand Down Expand Up @@ -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`.
Expand Down
80 changes: 40 additions & 40 deletions csbindgen-tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand All @@ -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 changes: 30 additions & 15 deletions csbindgen-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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)]
Expand Down
1 change: 1 addition & 0 deletions csbindgen-tests/src/others.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
pub enum HogeMoge{
X = 0,
Y = 1,
event = 2
}
2 changes: 1 addition & 1 deletion csbindgen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "csbindgen"
version = "1.3.0"
version = "1.4.0"
edition = "2021"
authors = [
"Yoshifumi Kawai <ils@neue.cc>",
Expand Down
13 changes: 9 additions & 4 deletions csbindgen/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(", ");
Expand All @@ -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 {
Expand Down Expand Up @@ -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" {
Expand Down
61 changes: 35 additions & 26 deletions csbindgen/src/type_meta.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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)
)
})
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
};
Expand Down Expand Up @@ -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(", ");
Expand Down
Loading

0 comments on commit 4d90061

Please sign in to comment.