mirror of
https://github.com/Sarsoo/csbindgen.git
synced 2024-12-22 22:46:26 +00:00
support NoNull, Box
This commit is contained in:
parent
7041ca7f48
commit
510750c6b6
19
csbindgen-tests/src/lib.rs
vendored
19
csbindgen-tests/src/lib.rs
vendored
@ -1,6 +1,6 @@
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
ffi::{c_char, c_long, c_ulong, CString}, ptr::NonNull,
|
||||
ffi::{c_char, c_long, c_ulong, CString}, ptr::NonNull, num::NonZeroI8,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -178,17 +178,22 @@ pub extern "C" fn test_func_issue_39(_f: extern "C" fn(i32)){
|
||||
pub extern "C" fn test_func_issue_39_variation1(_f: extern "C" fn(i32, i32, i32)){
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
// pub extern "C" fn nonnull_parameter(_output_word_uuid: NonNull<[u8; 16]>){
|
||||
// }
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nonnull_parameter(_output_word_uuid: NonNull<[u8; 16]>){
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
// pub extern "C" fn non_nonnull_parameter(_output_word_uuid: [u8; 16]){
|
||||
// }
|
||||
|
||||
// #[no_mangle]
|
||||
// pub extern "C" fn non_nonnull_parameter2(_output_word_uuid: NonNull<u8>){
|
||||
// }
|
||||
#[no_mangle]
|
||||
pub extern "C" fn non_nonnull_parameter2(_output_word_uuid: NonNull<u8>){
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nonzero_test(_a: NonZeroI8){
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ge(_f: extern "C" fn(i32, i32, i32)){
|
||||
|
@ -489,14 +489,24 @@ fn parse_type(t: &syn::Type) -> RustType {
|
||||
fn parse_type_path(t: &syn::TypePath) -> RustType {
|
||||
let last_segment = t.path.segments.last().unwrap();
|
||||
if let syn::PathArguments::AngleBracketed(x) = &last_segment.arguments {
|
||||
// generics, only supports Option<> for null function pointer
|
||||
if last_segment.ident == "Option" {
|
||||
// generics
|
||||
if let Some(syn::GenericArgument::Type(t)) = x.args.first() {
|
||||
let rust_type = parse_type(t);
|
||||
if last_segment.ident == "Option" {
|
||||
return RustType {
|
||||
type_name: "Option".to_string(),
|
||||
type_kind: TypeKind::Option(Box::new(rust_type)),
|
||||
};
|
||||
} else if last_segment.ident == "NonNull" {
|
||||
return RustType {
|
||||
type_name: "NonNull".to_string(),
|
||||
type_kind: TypeKind::Pointer(PointerType::NonNull, Box::new(rust_type)),
|
||||
};
|
||||
} else if last_segment.ident == "Box" {
|
||||
return RustType {
|
||||
type_name: "Box".to_string(),
|
||||
type_kind: TypeKind::Pointer(PointerType::Box, Box::new(rust_type)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ pub enum PointerType {
|
||||
MutPointerPointer,
|
||||
ConstMutPointerPointer,
|
||||
MutConstPointerPointer,
|
||||
Box,
|
||||
NonNull,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -112,7 +114,7 @@ impl RustType {
|
||||
pub fn to_rust_string(&self, type_path: &str) -> String {
|
||||
let mut sb = String::new();
|
||||
|
||||
fn emit_pointer(sb: &mut String, p: &PointerType) {
|
||||
fn emit_pointer(sb: &mut String, p: &PointerType) -> bool {
|
||||
match p {
|
||||
ConstPointer => sb.push_str("*const"),
|
||||
MutPointer => sb.push_str("*mut"),
|
||||
@ -120,7 +122,15 @@ impl RustType {
|
||||
MutPointerPointer => sb.push_str("*mut *mut"),
|
||||
ConstMutPointerPointer => sb.push_str("*const *mut"),
|
||||
MutConstPointerPointer => sb.push_str("*mut *const"),
|
||||
NonNull => sb.push_str("NonNull<"),
|
||||
Box => sb.push_str("Box<"),
|
||||
};
|
||||
|
||||
// return NonNull or Box requires close angle
|
||||
match p {
|
||||
NonNull | Box => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
let emit_type_name = |sb: &mut String| {
|
||||
@ -142,13 +152,17 @@ impl RustType {
|
||||
emit_type_name(&mut sb);
|
||||
}
|
||||
Pointer(p, inner) => {
|
||||
emit_pointer(&mut sb, p);
|
||||
let need_close = emit_pointer(&mut sb, p);
|
||||
sb.push(' ');
|
||||
sb.push_str(inner.to_rust_string(type_path).as_str());
|
||||
if need_close {
|
||||
sb.push('>');
|
||||
}
|
||||
}
|
||||
FixedArray(digits, pointer) => {
|
||||
let mut need_close = false;
|
||||
if let Some(p) = pointer {
|
||||
emit_pointer(&mut sb, p);
|
||||
need_close = emit_pointer(&mut sb, p);
|
||||
sb.push(' ');
|
||||
}
|
||||
|
||||
@ -157,6 +171,9 @@ impl RustType {
|
||||
sb.push_str("; ");
|
||||
sb.push_str(digits.as_str());
|
||||
sb.push(']');
|
||||
if need_close {
|
||||
sb.push('>');
|
||||
}
|
||||
}
|
||||
Function(parameters, return_type) => {
|
||||
emit_type_name(&mut sb); // extern fn
|
||||
@ -359,7 +376,7 @@ impl RustType {
|
||||
);
|
||||
}
|
||||
match p {
|
||||
MutPointer | ConstPointer => {
|
||||
MutPointer | ConstPointer | NonNull | Box => {
|
||||
sb.push('*');
|
||||
}
|
||||
MutPointerPointer
|
||||
|
10
dotnet-sandbox/NativeMethods.cs
vendored
10
dotnet-sandbox/NativeMethods.cs
vendored
@ -53,13 +53,13 @@ namespace CsBindgen
|
||||
public static extern void test_func_issue_39_variation1(delegate* unmanaged[Cdecl]<int, int, int, void> _f);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "nonnull_parameter", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void nonnull_parameter(NonNull _output_word_uuid);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "non_nonnull_parameter", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void non_nonnull_parameter(void/* byte[] */ _output_word_uuid);
|
||||
public static extern void nonnull_parameter(void/* byte[] */* _output_word_uuid);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "non_nonnull_parameter2", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void non_nonnull_parameter2(byte _output_word_uuid);
|
||||
public static extern void non_nonnull_parameter2(byte* _output_word_uuid);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "nonzero_test", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void nonzero_test(NonZeroI8 _a, U32Transparent _b);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "ge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void ge(delegate* unmanaged[Cdecl]<int, int, int, void> _f);
|
||||
|
Loading…
Reference in New Issue
Block a user