mirror of
https://github.com/Sarsoo/csbindgen.git
synced 2025-01-09 13:27:47 +00:00
Merge pull request #12 from Cysharp/fix-pointer-pointer
Fix pointer pointer
This commit is contained in:
commit
5e2911a2dc
52
README.md
52
README.md
@ -224,7 +224,7 @@ csbindgen::Builder::default()
|
||||
.input_bindgen_file("src/lz4.rs") // required
|
||||
.method_filter(|x| { x.starts_with("LZ4") } ) // optional, default: |x| !x.starts_with('_')
|
||||
.rust_method_prefix("csbindgen_") // optional, default: "csbindgen_"
|
||||
.rust_file_header("use super::lz4;") // optional, default: ""
|
||||
.rust_file_header("use super::lz4::*;") // optional, default: ""
|
||||
.rust_method_type_path("lz4") // optional, default: ""
|
||||
.csharp_dll_name("lz4") // required
|
||||
.csharp_class_name("NativeMethods") // optional, default: NativeMethods
|
||||
@ -369,6 +369,8 @@ Rust types will map these C# types.
|
||||
| `*const T` | `T*` |
|
||||
| `*mut *mut T` | `T**` |
|
||||
| `*const *const T` | `T**` |
|
||||
| `*mut *const T` | `T**` |
|
||||
| `*const *mut T` | `T**` |
|
||||
|
||||
csbindgen is designed to return primitives that do not cause marshalling. It is better to convert from pointers to Span yourself than to do the conversion implicitly and in a black box. This is a recent trend, such as the addition of [DisableRuntimeMarshalling](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.disableruntimemarshallingattribute) from .NET 7.
|
||||
|
||||
@ -814,7 +816,53 @@ finally
|
||||
}
|
||||
```
|
||||
|
||||
C# to Rust would be a bit simpler to send, just pass byte* and length. In Rust, use `std::slice::from_raw_parts` to create slice. Again, the important thing is that memory allocated in Rust must release in Rust and memory allocated in C# must release in C#.
|
||||
C# to Rust would be a bit simpler to send, just pass byte* and length. In Rust, use `std::slice::from_raw_parts` to create slice.
|
||||
|
||||
```rust
|
||||
#[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);
|
||||
}
|
||||
```
|
||||
|
||||
```csharp
|
||||
var str = "foobarbaz:あいうえお"; // JPN(Unicode)
|
||||
fixed (char* p = str)
|
||||
{
|
||||
NativeMethods.csharp_to_rust_string((ushort*)p, str.Length);
|
||||
}
|
||||
|
||||
var str2 = Encoding.UTF8.GetBytes("あいうえお:foobarbaz");
|
||||
fixed (byte* p = str2)
|
||||
{
|
||||
NativeMethods.csharp_to_rust_utf8(p, str2.Length);
|
||||
}
|
||||
|
||||
var bytes = new byte[] { 1, 10, 100, 255 };
|
||||
fixed (byte* p = bytes)
|
||||
{
|
||||
NativeMethods.csharp_to_rust_bytes(p, bytes.Length);
|
||||
}
|
||||
```
|
||||
|
||||
Again, the important thing is that memory allocated in Rust must release in Rust and memory allocated in C# must release in C#.
|
||||
|
||||
Build Tracing
|
||||
---
|
||||
|
8
csbindgen-tests/build.rs
vendored
8
csbindgen-tests/build.rs
vendored
@ -61,16 +61,17 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
csbindgen::Builder::default()
|
||||
.input_extern_file("src/lib.rs")
|
||||
.csharp_class_name("LibRust")
|
||||
.csharp_class_name("NativeMethods")
|
||||
.csharp_dll_name("csbindgen_tests")
|
||||
.csharp_use_function_pointer(true)
|
||||
.generate_csharp_file("../dotnet-sandbox/method_call.cs")
|
||||
.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_method_prefix("csbindgen_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")?;
|
||||
@ -78,6 +79,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
// csbindgen::Builder::new()
|
||||
// .input_bindgen_file("src/quiche.rs")
|
||||
// .method_filter(|x| x.starts_with("quiche_"))
|
||||
// .rust_file_header("use super::quiche::*;")
|
||||
// .rust_method_prefix("csbindgen_quiche_")
|
||||
// .csharp_class_name("LibQuiche")
|
||||
// .csharp_dll_name("libquiche")
|
||||
@ -86,7 +88,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
// csbindgen::Builder::new()
|
||||
// .input_bindgen_file("src/bullet3.rs")
|
||||
// .method_filter(|x| x.starts_with("b3"))
|
||||
// .rust_file_header("use super::bullet3::*;")
|
||||
// .rust_method_prefix("csbindgen_bullet3_")
|
||||
// .csharp_entry_point_prefix("csbindgen_bullet3_")
|
||||
// .csharp_class_name("LibBullet3")
|
||||
// .csharp_dll_name("libbullet3")
|
||||
// .generate_to_file("src/bullet3_ffi.rs", "../dotnet-sandbox/bullet3_bindgen.cs")?;
|
||||
|
28
csbindgen-tests/src/bullet3_ffi.rs
vendored
28
csbindgen-tests/src/bullet3_ffi.rs
vendored
@ -3,7 +3,7 @@
|
||||
#[allow(unused)]
|
||||
use ::std::os::raw::*;
|
||||
|
||||
|
||||
use super::bullet3::*;
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
@ -246,10 +246,10 @@ pub unsafe extern "C" fn csbindgen_bullet3_b3GetStatusActualState(
|
||||
bodyUniqueId: *mut c_int,
|
||||
numDegreeOfFreedomQ: *mut c_int,
|
||||
numDegreeOfFreedomU: *mut c_int,
|
||||
rootLocalInertialFrame: *mut *mut f64,
|
||||
actualStateQ: *mut *mut f64,
|
||||
actualStateQdot: *mut *mut f64,
|
||||
jointReactionForces: *mut *mut f64
|
||||
rootLocalInertialFrame: *mut *const f64,
|
||||
actualStateQ: *mut *const f64,
|
||||
actualStateQdot: *mut *const f64,
|
||||
jointReactionForces: *mut *const f64
|
||||
) -> c_int
|
||||
{
|
||||
b3GetStatusActualState(
|
||||
@ -271,14 +271,14 @@ pub unsafe extern "C" fn csbindgen_bullet3_b3GetStatusActualState2(
|
||||
numLinks: *mut c_int,
|
||||
numDegreeOfFreedomQ: *mut c_int,
|
||||
numDegreeOfFreedomU: *mut c_int,
|
||||
rootLocalInertialFrame: *mut *mut f64,
|
||||
actualStateQ: *mut *mut f64,
|
||||
actualStateQdot: *mut *mut f64,
|
||||
jointReactionForces: *mut *mut f64,
|
||||
linkLocalInertialFrames: *mut *mut f64,
|
||||
jointMotorForces: *mut *mut f64,
|
||||
linkStates: *mut *mut f64,
|
||||
linkWorldVelocities: *mut *mut f64
|
||||
rootLocalInertialFrame: *mut *const f64,
|
||||
actualStateQ: *mut *const f64,
|
||||
actualStateQdot: *mut *const f64,
|
||||
jointReactionForces: *mut *const f64,
|
||||
linkLocalInertialFrames: *mut *const f64,
|
||||
jointMotorForces: *mut *const f64,
|
||||
linkStates: *mut *const f64,
|
||||
linkWorldVelocities: *mut *const f64
|
||||
) -> c_int
|
||||
{
|
||||
b3GetStatusActualState2(
|
||||
@ -565,7 +565,7 @@ pub unsafe extern "C" fn csbindgen_bullet3_b3GetUserDataInfo(
|
||||
physClient: b3PhysicsClientHandle,
|
||||
bodyUniqueId: c_int,
|
||||
userDataIndex: c_int,
|
||||
keyOut: *mut *mut c_char,
|
||||
keyOut: *mut *const c_char,
|
||||
userDataIdOut: *mut c_int,
|
||||
linkIndexOut: *mut c_int,
|
||||
visualShapeIndexOut: *mut c_int
|
||||
|
64
csbindgen-tests/src/lib.rs
vendored
64
csbindgen-tests/src/lib.rs
vendored
@ -14,6 +14,39 @@ mod lz4;
|
||||
#[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 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;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type LONG_PTR = ::std::os::raw::c_longlong;
|
||||
#[allow(non_camel_case_types)]
|
||||
@ -34,6 +67,33 @@ pub unsafe extern "C" fn nullpointer_test(p: *const u8) {
|
||||
};
|
||||
}
|
||||
|
||||
#[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)
|
||||
@ -46,11 +106,11 @@ pub extern "C" fn csharp_to_rust(cb: extern "C" fn(x: i32, y: i32) -> i32) {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_to_csharp() -> extern fn(x: i32, y: i32) -> i32 {
|
||||
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 {
|
||||
extern "C" fn sum(x: i32, y: i32) -> i32 {
|
||||
x + y
|
||||
}
|
||||
|
||||
|
28
csbindgen-tests/src/quiche_ffi.rs
vendored
28
csbindgen-tests/src/quiche_ffi.rs
vendored
@ -3,7 +3,7 @@
|
||||
#[allow(unused)]
|
||||
use ::std::os::raw::*;
|
||||
|
||||
|
||||
use super::quiche::*;
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
@ -18,7 +18,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_version(
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_enable_debug_logging(
|
||||
cb: Option<extern "C" fn(line: *const c_char, argp: *mut c_void)>,
|
||||
cb: Option<unsafe extern "C" fn(line: *const c_char, argp: *mut c_void)>,
|
||||
argp: *mut c_void
|
||||
) -> c_int
|
||||
{
|
||||
@ -899,7 +899,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_close(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_trace_id(
|
||||
conn: *const quiche_conn,
|
||||
out: *mut *mut u8,
|
||||
out: *mut *const u8,
|
||||
out_len: *mut usize
|
||||
)
|
||||
{
|
||||
@ -913,7 +913,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_trace_id(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_source_id(
|
||||
conn: *const quiche_conn,
|
||||
out: *mut *mut u8,
|
||||
out: *mut *const u8,
|
||||
out_len: *mut usize
|
||||
)
|
||||
{
|
||||
@ -927,7 +927,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_source_id(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_destination_id(
|
||||
conn: *const quiche_conn,
|
||||
out: *mut *mut u8,
|
||||
out: *mut *const u8,
|
||||
out_len: *mut usize
|
||||
)
|
||||
{
|
||||
@ -941,7 +941,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_destination_id(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_application_proto(
|
||||
conn: *const quiche_conn,
|
||||
out: *mut *mut u8,
|
||||
out: *mut *const u8,
|
||||
out_len: *mut usize
|
||||
)
|
||||
{
|
||||
@ -955,7 +955,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_application_proto(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_peer_cert(
|
||||
conn: *const quiche_conn,
|
||||
out: *mut *mut u8,
|
||||
out: *mut *const u8,
|
||||
out_len: *mut usize
|
||||
)
|
||||
{
|
||||
@ -969,7 +969,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_peer_cert(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_session(
|
||||
conn: *const quiche_conn,
|
||||
out: *mut *mut u8,
|
||||
out: *mut *const u8,
|
||||
out_len: *mut usize
|
||||
)
|
||||
{
|
||||
@ -1065,7 +1065,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_peer_error(
|
||||
conn: *const quiche_conn,
|
||||
is_app: *mut bool,
|
||||
error_code: *mut u64,
|
||||
reason: *mut *mut u8,
|
||||
reason: *mut *const u8,
|
||||
reason_len: *mut usize
|
||||
) -> bool
|
||||
{
|
||||
@ -1083,7 +1083,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_local_error(
|
||||
conn: *const quiche_conn,
|
||||
is_app: *mut bool,
|
||||
error_code: *mut u64,
|
||||
reason: *mut *mut u8,
|
||||
reason: *mut *const u8,
|
||||
reason_len: *mut usize
|
||||
) -> bool
|
||||
{
|
||||
@ -1261,7 +1261,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_dgram_send(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_conn_dgram_purge_outgoing(
|
||||
conn: *mut quiche_conn,
|
||||
f: Option<extern "C" fn(arg1: *mut u8, arg2: usize) -> bool>
|
||||
f: Option<unsafe extern "C" fn(arg1: *mut u8, arg2: usize) -> bool>
|
||||
)
|
||||
{
|
||||
quiche_conn_dgram_purge_outgoing(
|
||||
@ -1427,7 +1427,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_h3_event_type(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_h3_event_for_each_header(
|
||||
ev: *mut quiche_h3_event,
|
||||
cb: Option<extern "C" fn(name: *mut u8, name_len: usize, value: *mut u8, value_len: usize, argp: *mut c_void) -> c_int>,
|
||||
cb: Option<unsafe extern "C" fn(name: *mut u8, name_len: usize, value: *mut u8, value_len: usize, argp: *mut c_void) -> c_int>,
|
||||
argp: *mut c_void
|
||||
) -> c_int
|
||||
{
|
||||
@ -1441,7 +1441,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_h3_event_for_each_header(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_h3_for_each_setting(
|
||||
conn: *mut quiche_h3_conn,
|
||||
cb: Option<extern "C" fn(identifier: u64, value: u64, argp: *mut c_void) -> c_int>,
|
||||
cb: Option<unsafe extern "C" fn(identifier: u64, value: u64, argp: *mut c_void) -> c_int>,
|
||||
argp: *mut c_void
|
||||
) -> c_int
|
||||
{
|
||||
@ -1614,7 +1614,7 @@ pub unsafe extern "C" fn csbindgen_quiche_quiche_h3_send_priority_update_for_req
|
||||
pub unsafe extern "C" fn csbindgen_quiche_quiche_h3_take_last_priority_update(
|
||||
conn: *mut quiche_h3_conn,
|
||||
prioritized_element_id: u64,
|
||||
cb: Option<extern "C" fn(priority_field_value: *mut u8, priority_field_value_len: u64, argp: *mut c_void) -> c_int>,
|
||||
cb: Option<unsafe extern "C" fn(priority_field_value: *mut u8, priority_field_value_len: u64, argp: *mut c_void) -> c_int>,
|
||||
argp: *mut c_void
|
||||
) -> c_int
|
||||
{
|
||||
|
2
csbindgen-tests/src/zstd_ffi.rs
vendored
2
csbindgen-tests/src/zstd_ffi.rs
vendored
@ -3,7 +3,7 @@
|
||||
#[allow(unused)]
|
||||
use ::std::os::raw::*;
|
||||
|
||||
|
||||
use super::zstd::*;
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "csbindgen"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
edition = "2021"
|
||||
authors = [
|
||||
"Yoshifumi Kawai <ils@neue.cc>",
|
||||
|
@ -258,8 +258,7 @@ pub fn reduce_enum(
|
||||
fn parse_type(t: &syn::Type) -> RustType {
|
||||
match t {
|
||||
syn::Type::Ptr(t) => {
|
||||
let has_const = t.const_token.is_some();
|
||||
// let has_mut = t.mutability.is_some();
|
||||
let has_const = t.const_token.is_some(); // not is has_mut
|
||||
|
||||
if let syn::Type::Path(path) = &*t.elem {
|
||||
return RustType {
|
||||
@ -272,13 +271,18 @@ fn parse_type(t: &syn::Type) -> RustType {
|
||||
};
|
||||
} else if let syn::Type::Ptr(t) = &*t.elem {
|
||||
if let syn::Type::Path(path) = &*t.elem {
|
||||
let has_const2 = t.const_token.is_some();
|
||||
|
||||
let pointer_type = match (has_const, has_const2) {
|
||||
(true, true) => PointerType::ConstPointerPointer,
|
||||
(true, false) => PointerType::ConstMutPointerPointer,
|
||||
(false, true) => PointerType::MutConstPointerPointer,
|
||||
(false, false) => PointerType::MutPointerPointer,
|
||||
};
|
||||
|
||||
return RustType {
|
||||
type_name: path.path.segments.last().unwrap().ident.to_string(),
|
||||
type_kind: TypeKind::Pointer(if has_const {
|
||||
PointerType::ConstPointerPointer
|
||||
} else {
|
||||
PointerType::MutPointerPointer
|
||||
}),
|
||||
type_kind: TypeKind::Pointer(pointer_type),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -345,7 +349,7 @@ fn parse_type(t: &syn::Type) -> RustType {
|
||||
};
|
||||
|
||||
return RustType {
|
||||
type_name: "extern \"C\" fn".to_string(),
|
||||
type_name: "unsafe extern \"C\" fn".to_string(),
|
||||
type_kind: TypeKind::Function(parameters, ret),
|
||||
};
|
||||
}
|
||||
|
@ -77,6 +77,8 @@ pub enum PointerType {
|
||||
MutPointer,
|
||||
ConstPointerPointer,
|
||||
MutPointerPointer,
|
||||
ConstMutPointerPointer,
|
||||
MutConstPointerPointer
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -103,6 +105,8 @@ impl RustType {
|
||||
MutPointer => sb.push_str("*mut"),
|
||||
ConstPointerPointer => sb.push_str("*const *const"),
|
||||
MutPointerPointer => sb.push_str("*mut *mut"),
|
||||
ConstMutPointerPointer =>sb.push_str("*const *mut"),
|
||||
MutConstPointerPointer =>sb.push_str("*mut *const"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -305,12 +309,13 @@ impl RustType {
|
||||
sb.push_str(convert_type_name(use_type.type_name.as_str()));
|
||||
|
||||
if use_alias {
|
||||
use PointerType::*;
|
||||
if let TypeKind::Pointer(p) = &use_type.type_kind {
|
||||
match p {
|
||||
PointerType::MutPointer | PointerType::ConstPointer => {
|
||||
MutPointer | ConstPointer => {
|
||||
sb.push('*');
|
||||
}
|
||||
PointerType::MutPointerPointer | PointerType::ConstPointerPointer => {
|
||||
MutPointerPointer | ConstPointerPointer | MutConstPointerPointer | ConstMutPointerPointer => {
|
||||
sb.push_str("**");
|
||||
}
|
||||
}
|
||||
@ -318,11 +323,12 @@ impl RustType {
|
||||
}
|
||||
|
||||
if let TypeKind::Pointer(p) = &self.type_kind {
|
||||
use PointerType::*;
|
||||
match p {
|
||||
PointerType::MutPointer | PointerType::ConstPointer => {
|
||||
MutPointer | ConstPointer => {
|
||||
sb.push('*');
|
||||
}
|
||||
PointerType::MutPointerPointer | PointerType::ConstPointerPointer => {
|
||||
MutPointerPointer | ConstPointerPointer | MutConstPointerPointer | ConstMutPointerPointer => {
|
||||
sb.push_str("**");
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace CsBindgen
|
||||
{
|
||||
internal static unsafe partial class LibRust
|
||||
internal static unsafe partial class NativeMethods
|
||||
{
|
||||
const string __DllName = "csbindgen_tests";
|
||||
|
||||
@ -21,6 +21,15 @@ namespace CsBindgen
|
||||
[DllImport(__DllName, EntryPoint = "nullpointer_test", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void nullpointer_test(byte* p);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "csharp_to_rust_string", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void csharp_to_rust_string(ushort* utf16_str, int utf16_len);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "csharp_to_rust_utf8", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void csharp_to_rust_utf8(byte* utf8_str, int utf8_len);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "csharp_to_rust_bytes", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void csharp_to_rust_bytes(byte* bytes, int len);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "callback_test", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int callback_test(delegate* unmanaged[Cdecl]<int, int> cb);
|
||||
|
47
dotnet-sandbox/Program.cs
vendored
47
dotnet-sandbox/Program.cs
vendored
@ -15,19 +15,44 @@ unsafe
|
||||
{
|
||||
|
||||
|
||||
LibRust.alias_test1(null);
|
||||
|
||||
//LibRust.call_bindgen_lz4();
|
||||
//NativeMethods.call_bindgen_lz4();
|
||||
|
||||
|
||||
var str = "foobarbaz:あいうえお"; // JPN(Unicode)
|
||||
fixed (char* p = str)
|
||||
{
|
||||
NativeMethods.csharp_to_rust_string((ushort*)p, str.Length);
|
||||
}
|
||||
|
||||
var str2 = Encoding.UTF8.GetBytes("あいうえお:foobarbaz");
|
||||
fixed (byte* p = str2)
|
||||
{
|
||||
NativeMethods.csharp_to_rust_utf8(p, str2.Length);
|
||||
}
|
||||
|
||||
var bytes = new byte[] { 1, 10, 100, 255 };
|
||||
fixed (byte* p = bytes)
|
||||
{
|
||||
NativeMethods.csharp_to_rust_bytes(p, bytes.Length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//NativeMethods.csharp_to_rust_utf8
|
||||
//NativeMethods.alias_test1(null);
|
||||
|
||||
|
||||
|
||||
|
||||
// C# -> Rust, pass static UnmanagedCallersOnly method with `&`
|
||||
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
|
||||
static int Sum(int x, int y) => x + y;
|
||||
|
||||
LibRust.csharp_to_rust(&Sum);
|
||||
NativeMethods.csharp_to_rust(&Sum);
|
||||
|
||||
// Rust -> C#, get typed delegate*
|
||||
var f = LibRust.rust_to_csharp();
|
||||
var f = NativeMethods.rust_to_csharp();
|
||||
|
||||
var v = f(20, 30);
|
||||
Console.WriteLine(v); // 50
|
||||
@ -49,18 +74,18 @@ unsafe
|
||||
//Console.WriteLine(cc);
|
||||
|
||||
|
||||
var context = LibRust.create_context();
|
||||
// var context = LibRust.create_context();
|
||||
|
||||
// do anything...
|
||||
// // do anything...
|
||||
|
||||
LibRust.delete_context(context);
|
||||
// LibRust.delete_context(context);
|
||||
|
||||
var ctx = LibRust.create_counter_context(); // ctx = void*
|
||||
//var ctx = LibRust.create_counter_context(); // ctx = void*
|
||||
|
||||
LibRust.insert_counter_context(ctx, 10);
|
||||
LibRust.insert_counter_context(ctx, 20);
|
||||
//LibRust.insert_counter_context(ctx, 10);
|
||||
//LibRust.insert_counter_context(ctx, 20);
|
||||
|
||||
LibRust.delete_counter_context(ctx);
|
||||
//LibRust.delete_counter_context(ctx);
|
||||
|
||||
//LibRust.insert_counter_context(ctx, 20);
|
||||
//LibRust.insert_counter_context(ctx, 30);
|
||||
|
878
dotnet-sandbox/bullet3_bindgen.cs
vendored
878
dotnet-sandbox/bullet3_bindgen.cs
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user