support NoNull, Box

This commit is contained in:
neuecc 2023-09-05 16:00:50 +09:00
parent 7041ca7f48
commit 510750c6b6
4 changed files with 53 additions and 21 deletions

View File

@ -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)){

View File

@ -257,7 +257,7 @@ pub fn collect_const(ast: &syn::File, result: &mut Vec<RustConst>) {
format!("{}", i.base10_parse::<i64>().unwrap())
}
syn::Lit::Float(f) => {
format!("{}", f.base10_parse::<f64>().unwrap())
format!("{}", f.base10_parse::<f64>().unwrap())
}
syn::Lit::Bool(b) => {
format!("{}", b.value)
@ -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" {
if let Some(syn::GenericArgument::Type(t)) = x.args.first() {
let rust_type = parse_type(t);
// 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)),
};
}
}
}

View File

@ -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

View File

@ -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);