allow input_extern_file read multiple files

This commit is contained in:
neuecc 2023-03-17 17:03:05 +09:00
parent ac198bd776
commit f163a32e0c
7 changed files with 80 additions and 46 deletions

View File

@ -84,6 +84,8 @@ fn main() -> Result<(), Box<dyn Error>> {
csbindgen::Builder::default()
.input_extern_file("src/lib.rs")
.input_extern_file("src/others.rs")
//.input_extern_files(&["src/lib.rs"])
.csharp_class_name("NativeMethods")
.csharp_dll_name("csbindgen_tests")
.csharp_use_function_pointer(true)

View File

@ -3,6 +3,8 @@ use std::{
ffi::{c_char, c_long, c_ulong, c_void, CString},
};
#[allow(dead_code)]
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
@ -58,6 +60,14 @@ mod lz4_ffi;
// #[allow(non_camel_case_types)]
// mod zstd_ffi;
mod others;
pub use others::HogeMoge;
#[no_mangle]
pub extern "C" fn other_1(hoge: HogeMoge){
println!("{}", hoge);
}
#[no_mangle]
pub extern "C" fn nest_test(
_f: ::std::option::Option<
@ -74,6 +84,7 @@ pub extern "C" fn nest_test(
#[allow(non_camel_case_types)]
pub type LONG_PTR = ::std::os::raw::c_longlong;
#[allow(non_camel_case_types)]

9
csbindgen-tests/src/others.rs vendored Normal file
View File

@ -0,0 +1,9 @@
#[repr(i32)]
#[derive(Debug, Copy, Clone)]
pub enum HogeMoge{
X = 0,
Y = 1,
}

View File

@ -13,7 +13,7 @@ pub struct Builder {
pub struct BindgenOptions {
pub input_bindgen_file: String,
pub input_extern_file: String,
pub input_extern_files: Vec<String>,
pub method_filter: fn(method_name: String) -> bool,
pub rust_method_type_path: String,
pub rust_method_prefix: String,
@ -34,7 +34,7 @@ impl Default for Builder {
Self {
options: BindgenOptions {
input_bindgen_file: "".to_string(),
input_extern_file: "".to_string(),
input_extern_files: vec![],
method_filter: |x| !x.starts_with('_'),
rust_method_type_path: "".to_string(),
rust_method_prefix: "csbindgen_".to_string(),
@ -47,7 +47,7 @@ impl Default for Builder {
csharp_class_accessibility: "internal".to_string(),
csharp_if_symbol: "".to_string(),
csharp_if_dll_name: "".to_string(),
csharp_use_function_pointer: true
csharp_use_function_pointer: true,
},
}
}
@ -64,9 +64,11 @@ impl Builder {
self
}
/// Change an input .rs file for collect extern methods to C# binding.
/// Add an input .rs file for collect extern methods to C# binding.
pub fn input_extern_file<T: Into<String>>(mut self, input_extern_file: T) -> Builder {
self.options.input_extern_file = input_extern_file.into();
self.options
.input_extern_files
.push(input_extern_file.into());
self
}
@ -137,7 +139,10 @@ impl Builder {
/// configure C# class accessibility, default is internal
/// `{csharp_class_accessibility} static unsafe partial class NativeMethods`
pub fn csharp_class_accessibility<T: Into<String>>(mut self, csharp_class_accessibility: T) -> Builder {
pub fn csharp_class_accessibility<T: Into<String>>(
mut self,
csharp_class_accessibility: T,
) -> Builder {
self.options.csharp_class_accessibility = csharp_class_accessibility.into();
self
}
@ -168,7 +173,7 @@ impl Builder {
csharp_file.flush()?;
}
if !self.options.input_extern_file.is_empty() {
if !self.options.input_extern_files.is_empty() {
let (_, csharp) = generate(GenerateKind::InputExtern, &self.options)?;
let mut csharp_file = make_file(csharp_output_path.as_ref())?;
@ -199,7 +204,7 @@ impl Builder {
csharp_file.flush()?;
}
if !self.options.input_extern_file.is_empty() {
if !self.options.input_extern_files.is_empty() {
let (rust, csharp) = generate(GenerateKind::InputExtern, &self.options)?;
if let Some(rust) = rust {

View File

@ -14,7 +14,7 @@ use emitter::*;
use field_map::FieldMap;
use parser::*;
use std::{collections::HashSet, error::Error};
use type_meta::RustType;
use type_meta::{ExternMethod, RustEnum, RustStruct, RustType};
enum GenerateKind {
InputBindgen,
@ -25,21 +25,30 @@ pub(crate) fn generate(
generate_kind: GenerateKind,
options: &BindgenOptions,
) -> Result<(Option<String>, String), Box<dyn Error>> {
let path = match generate_kind {
GenerateKind::InputBindgen => &options.input_bindgen_file,
GenerateKind::InputExtern => &options.input_extern_file,
let temp_input = [options.input_bindgen_file.clone()];
let (paths, generate_rust) = match generate_kind {
GenerateKind::InputBindgen => (temp_input.as_slice(), true),
GenerateKind::InputExtern => (options.input_extern_files.as_slice(), false),
};
let file_content = std::fs::read_to_string(path)
.expect(("input file not found, path:".to_string() + path).as_str());
let file_ast = syn::parse_file(file_content.as_str())?;
let (methods, generate_rust) = match generate_kind {
GenerateKind::InputBindgen => (collect_foreign_method(&file_ast, options), true),
GenerateKind::InputExtern => (collect_extern_method(&file_ast, options), false),
};
let aliases = collect_type_alias(&file_ast);
let structs = collect_struct(&file_ast);
let enums = collect_enum(&file_ast);
let mut methods: Vec<ExternMethod> = vec![];
let mut aliases = AliasMap::new();
let mut structs: Vec<RustStruct> = vec![];
let mut enums: Vec<RustEnum> = vec![];
for path in paths {
let file_content = std::fs::read_to_string(path)
.expect(("input file not found, path:".to_string() + path).as_str());
let file_ast = syn::parse_file(file_content.as_str())?;
match generate_kind {
GenerateKind::InputBindgen => collect_foreign_method(&file_ast, options, &mut methods),
GenerateKind::InputExtern => collect_extern_method(&file_ast, options, &mut methods),
};
collect_type_alias(&file_ast, &mut aliases);
collect_struct(&file_ast, &mut structs);
collect_enum(&file_ast, &mut enums);
}
// collect using_types
let mut using_types = HashSet::new();

View File

@ -7,9 +7,11 @@ enum FnItem {
Item(syn::ItemFn),
}
pub fn collect_foreign_method(ast: &syn::File, options: &BindgenOptions) -> Vec<ExternMethod> {
let mut list: Vec<ExternMethod> = Vec::new();
pub fn collect_foreign_method(
ast: &syn::File,
options: &BindgenOptions,
list: &mut Vec<ExternMethod>,
) {
for item in ast.items.iter() {
if let Item::ForeignMod(m) = item {
for item in m.items.iter() {
@ -22,13 +24,13 @@ pub fn collect_foreign_method(ast: &syn::File, options: &BindgenOptions) -> Vec<
}
}
}
list
}
pub fn collect_extern_method(ast: &syn::File, options: &BindgenOptions) -> Vec<ExternMethod> {
let mut list: Vec<ExternMethod> = Vec::new();
pub fn collect_extern_method(
ast: &syn::File,
options: &BindgenOptions,
list: &mut Vec<ExternMethod>,
) {
for item in ast.items.iter() {
if let Item::Fn(m) = item {
if m.sig.abi.is_some() {
@ -40,8 +42,6 @@ pub fn collect_extern_method(ast: &syn::File, options: &BindgenOptions) -> Vec<E
}
}
}
list
}
fn parse_method(item: FnItem, options: &BindgenOptions) -> Option<ExternMethod> {
@ -112,8 +112,7 @@ fn parse_method(item: FnItem, options: &BindgenOptions) -> Option<ExternMethod>
None
}
pub fn collect_type_alias(ast: &syn::File) -> AliasMap {
let mut result = AliasMap::new();
pub fn collect_type_alias(ast: &syn::File, result: &mut AliasMap) {
for item in ast.items.iter() {
if let Item::Type(t) = item {
let name = t.ident.to_string();
@ -135,14 +134,10 @@ pub fn collect_type_alias(ast: &syn::File) -> AliasMap {
}
}
}
result
}
pub fn collect_struct(ast: &syn::File) -> Vec<RustStruct> {
pub fn collect_struct(ast: &syn::File, result: &mut Vec<RustStruct>) {
// collect union or struct
let mut result = Vec::new();
for item in ast.items.iter() {
if let Item::Union(t) = item {
let struct_name = t.ident.to_string();
@ -165,8 +160,6 @@ pub fn collect_struct(ast: &syn::File) -> Vec<RustStruct> {
};
}
}
result
}
fn collect_fields(fields: &syn::FieldsNamed) -> Vec<FieldMember> {
@ -185,9 +178,7 @@ fn collect_fields(fields: &syn::FieldsNamed) -> Vec<FieldMember> {
result
}
pub fn collect_enum(ast: &syn::File) -> Vec<RustEnum> {
let mut result = Vec::new();
pub fn collect_enum(ast: &syn::File, result: &mut Vec<RustEnum>) {
for item in ast.items.iter() {
if let Item::Enum(t) = item {
let mut repr = None;
@ -221,8 +212,6 @@ pub fn collect_enum(ast: &syn::File) -> Vec<RustEnum> {
});
}
}
result
}
pub fn reduce_struct(

View File

@ -12,6 +12,9 @@ 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 = "nest_test", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void nest_test(delegate* unmanaged[Cdecl]<delegate* unmanaged[Cdecl]<int, void>*, int> _f);
@ -173,6 +176,12 @@ namespace CsBindgen
C = 10,
}
internal enum HogeMoge : int
{
X = 0,
Y = 1,
}
}