diff options
-rw-r--r-- | src/codegen/dyngen.rs | 63 | ||||
-rw-r--r-- | src/codegen/mod.rs | 8 | ||||
-rw-r--r-- | tests/expectations/tests/dynamic_loading_simple.rs | 25 | ||||
-rw-r--r-- | tests/expectations/tests/dynamic_loading_template.rs | 20 | ||||
-rw-r--r-- | tests/expectations/tests/dynamic_loading_with_blacklist.rs | 20 | ||||
-rw-r--r-- | tests/expectations/tests/dynamic_loading_with_class.rs | 20 | ||||
-rw-r--r-- | tests/expectations/tests/dynamic_loading_with_whitelist.rs | 29 | ||||
-rw-r--r-- | tests/headers/dynamic_loading_with_whitelist.hpp | 3 |
8 files changed, 49 insertions, 139 deletions
diff --git a/src/codegen/dyngen.rs b/src/codegen/dyngen.rs index 4cd01c01..65872ea2 100644 --- a/src/codegen/dyngen.rs +++ b/src/codegen/dyngen.rs @@ -8,7 +8,7 @@ pub struct DynamicItems { /// ```ignore /// struct Lib { /// __library: ::libloading::Library, - /// x: Result<unsafe extern ..., ::libloading::Error>, // <- tracks these + /// pub x: Result<unsafe extern ..., ::libloading::Error>, // <- tracks these /// ... /// } /// ``` @@ -26,15 +26,6 @@ pub struct DynamicItems { /// ``` struct_implementation: Vec<proc_macro2::TokenStream>, - /// Tracks the tokens that will appear inside the struct used for checking if a symbol is - /// usable, e.g.: - /// ```ignore - /// pub fn f(&self) -> Result<(), &'a ::libloading::Error> { // <- tracks these - /// self.__library.f.as_ref().map(|_| ()) - /// } - /// ``` - runtime_checks: Vec<proc_macro2::TokenStream>, - /// Tracks the initialization of the fields inside the `::new` constructor of the library /// struct, e.g.: /// ```ignore @@ -80,16 +71,11 @@ impl DynamicItems { Self::default() } - pub fn get_tokens( - &self, - lib_ident: Ident, - check_struct_ident: Ident, - ) -> proc_macro2::TokenStream { + pub fn get_tokens(&self, lib_ident: Ident) -> proc_macro2::TokenStream { let struct_members = &self.struct_members; let constructor_inits = &self.constructor_inits; let init_fields = &self.init_fields; let struct_implementation = &self.struct_implementation; - let runtime_checks = &self.runtime_checks; quote! { extern crate libloading; @@ -107,26 +93,14 @@ impl DynamicItems { #( #constructor_inits )* Ok( #lib_ident { - __library: __library, + __library, #( #init_fields ),* } ) } - pub fn can_call(&self) -> #check_struct_ident { - #check_struct_ident { __library: self } - } - #( #struct_implementation )* } - - pub struct #check_struct_ident<'a> { - __library: &'a #lib_ident, - } - - impl<'a> #check_struct_ident<'a> { - #( #runtime_checks )* - } } } @@ -134,29 +108,30 @@ impl DynamicItems { &mut self, ident: Ident, abi: Abi, + is_variadic: bool, args: Vec<proc_macro2::TokenStream>, args_identifiers: Vec<proc_macro2::TokenStream>, ret: proc_macro2::TokenStream, ret_ty: proc_macro2::TokenStream, ) { - assert_eq!(args.len(), args_identifiers.len()); - - self.struct_members.push(quote!{ - #ident: Result<unsafe extern #abi fn ( #( #args ),* ) #ret, ::libloading::Error>, - }); + if !is_variadic { + assert_eq!(args.len(), args_identifiers.len()); + } - self.struct_implementation.push(quote! { - pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty { - let sym = self.#ident.as_ref().expect("Expected function, got error."); - (sym)(#( #args_identifiers ),*) - } + self.struct_members.push(quote! { + pub #ident: Result<unsafe extern #abi fn ( #( #args ),* ) #ret, ::libloading::Error>, }); - self.runtime_checks.push(quote! { - pub fn #ident (&self) -> Result<(), &'a::libloading::Error> { - self.__library.#ident.as_ref().map(|_| ()) - } - }); + // We can't implement variadic functions from C easily, so we allow to + // access the function pointer so that the user can call it just fine. + if !is_variadic { + self.struct_implementation.push(quote! { + pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty { + let sym = self.#ident.as_ref().expect("Expected function, got error."); + (sym)(#( #args_identifiers ),*) + } + }); + } let ident_str = ident.to_string(); self.constructor_inits.push(quote! { diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 64f95f4c..754c2c8b 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3808,6 +3808,7 @@ impl CodeGenerator for Function { result.dynamic_items().push( ident, abi, + signature.is_variadic(), args, args_identifiers, ret, @@ -4107,11 +4108,8 @@ pub(crate) fn codegen( if let Some(ref lib_name) = context.options().dynamic_library_name { let lib_ident = context.rust_ident(lib_name); - let check_struct_ident = - context.rust_ident(format!("Check{}", lib_name)); - let dynamic_items_tokens = result - .dynamic_items() - .get_tokens(lib_ident, check_struct_ident); + let dynamic_items_tokens = + result.dynamic_items().get_tokens(lib_ident); result.push(dynamic_items_tokens); } diff --git a/tests/expectations/tests/dynamic_loading_simple.rs b/tests/expectations/tests/dynamic_loading_simple.rs index b195a05d..b40711d8 100644 --- a/tests/expectations/tests/dynamic_loading_simple.rs +++ b/tests/expectations/tests/dynamic_loading_simple.rs @@ -8,20 +8,20 @@ extern crate libloading; pub struct TestLib { __library: ::libloading::Library, - foo: Result< + pub foo: Result< unsafe extern "C" fn( x: ::std::os::raw::c_int, y: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int, ::libloading::Error, >, - bar: Result< + pub bar: Result< unsafe extern "C" fn( x: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int, ::libloading::Error, >, - baz: Result< + pub baz: Result< unsafe extern "C" fn() -> ::std::os::raw::c_int, ::libloading::Error, >, @@ -36,15 +36,12 @@ impl TestLib { let bar = __library.get("bar".as_bytes()).map(|sym| *sym); let baz = __library.get("baz".as_bytes()).map(|sym| *sym); Ok(TestLib { - __library: __library, + __library, foo, bar, baz, }) } - pub fn can_call(&self) -> CheckTestLib { - CheckTestLib { __library: self } - } pub unsafe fn foo( &self, x: ::std::os::raw::c_int, @@ -65,17 +62,3 @@ impl TestLib { (sym)() } } -pub struct CheckTestLib<'a> { - __library: &'a TestLib, -} -impl<'a> CheckTestLib<'a> { - pub fn foo(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.foo.as_ref().map(|_| ()) - } - pub fn bar(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.bar.as_ref().map(|_| ()) - } - pub fn baz(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.baz.as_ref().map(|_| ()) - } -} diff --git a/tests/expectations/tests/dynamic_loading_template.rs b/tests/expectations/tests/dynamic_loading_template.rs index b9fa1698..e24599de 100644 --- a/tests/expectations/tests/dynamic_loading_template.rs +++ b/tests/expectations/tests/dynamic_loading_template.rs @@ -8,11 +8,11 @@ extern crate libloading; pub struct TestLib { __library: ::libloading::Library, - foo: Result< + pub foo: Result< unsafe extern "C" fn(x: ::std::os::raw::c_int) -> ::std::os::raw::c_int, ::libloading::Error, >, - foo1: Result<unsafe extern "C" fn(x: f32) -> f32, ::libloading::Error>, + pub foo1: Result<unsafe extern "C" fn(x: f32) -> f32, ::libloading::Error>, } impl TestLib { pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error> @@ -23,14 +23,11 @@ impl TestLib { let foo = __library.get("foo".as_bytes()).map(|sym| *sym); let foo1 = __library.get("foo1".as_bytes()).map(|sym| *sym); Ok(TestLib { - __library: __library, + __library, foo, foo1, }) } - pub fn can_call(&self) -> CheckTestLib { - CheckTestLib { __library: self } - } pub unsafe fn foo( &self, x: ::std::os::raw::c_int, @@ -43,14 +40,3 @@ impl TestLib { (sym)(x) } } -pub struct CheckTestLib<'a> { - __library: &'a TestLib, -} -impl<'a> CheckTestLib<'a> { - pub fn foo(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.foo.as_ref().map(|_| ()) - } - pub fn foo1(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.foo1.as_ref().map(|_| ()) - } -} diff --git a/tests/expectations/tests/dynamic_loading_with_blacklist.rs b/tests/expectations/tests/dynamic_loading_with_blacklist.rs index 259054b2..b3f6eb95 100644 --- a/tests/expectations/tests/dynamic_loading_with_blacklist.rs +++ b/tests/expectations/tests/dynamic_loading_with_blacklist.rs @@ -59,13 +59,13 @@ impl X { extern crate libloading; pub struct TestLib { __library: ::libloading::Library, - foo: Result< + pub foo: Result< unsafe extern "C" fn( x: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int, ::libloading::Error, >, - bar: Result< + pub bar: Result< unsafe extern "C" fn( x: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int, @@ -81,14 +81,11 @@ impl TestLib { let foo = __library.get("foo".as_bytes()).map(|sym| *sym); let bar = __library.get("bar".as_bytes()).map(|sym| *sym); Ok(TestLib { - __library: __library, + __library, foo, bar, }) } - pub fn can_call(&self) -> CheckTestLib { - CheckTestLib { __library: self } - } pub unsafe fn foo( &self, x: *mut ::std::os::raw::c_void, @@ -104,14 +101,3 @@ impl TestLib { (sym)(x) } } -pub struct CheckTestLib<'a> { - __library: &'a TestLib, -} -impl<'a> CheckTestLib<'a> { - pub fn foo(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.foo.as_ref().map(|_| ()) - } - pub fn bar(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.bar.as_ref().map(|_| ()) - } -} diff --git a/tests/expectations/tests/dynamic_loading_with_class.rs b/tests/expectations/tests/dynamic_loading_with_class.rs index 636f01bb..6c98caef 100644 --- a/tests/expectations/tests/dynamic_loading_with_class.rs +++ b/tests/expectations/tests/dynamic_loading_with_class.rs @@ -59,13 +59,13 @@ impl A { extern crate libloading; pub struct TestLib { __library: ::libloading::Library, - foo: Result< + pub foo: Result< unsafe extern "C" fn( x: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int, ::libloading::Error, >, - bar: Result<unsafe extern "C" fn(), ::libloading::Error>, + pub bar: Result<unsafe extern "C" fn(), ::libloading::Error>, } impl TestLib { pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error> @@ -76,14 +76,11 @@ impl TestLib { let foo = __library.get("foo".as_bytes()).map(|sym| *sym); let bar = __library.get("bar".as_bytes()).map(|sym| *sym); Ok(TestLib { - __library: __library, + __library, foo, bar, }) } - pub fn can_call(&self) -> CheckTestLib { - CheckTestLib { __library: self } - } pub unsafe fn foo( &self, x: *mut ::std::os::raw::c_void, @@ -96,14 +93,3 @@ impl TestLib { (sym)() } } -pub struct CheckTestLib<'a> { - __library: &'a TestLib, -} -impl<'a> CheckTestLib<'a> { - pub fn foo(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.foo.as_ref().map(|_| ()) - } - pub fn bar(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.bar.as_ref().map(|_| ()) - } -} diff --git a/tests/expectations/tests/dynamic_loading_with_whitelist.rs b/tests/expectations/tests/dynamic_loading_with_whitelist.rs index a1f8a2a4..0fcdf1da 100644 --- a/tests/expectations/tests/dynamic_loading_with_whitelist.rs +++ b/tests/expectations/tests/dynamic_loading_with_whitelist.rs @@ -8,18 +8,25 @@ extern crate libloading; pub struct TestLib { __library: ::libloading::Library, - foo: Result< + pub foo: Result< unsafe extern "C" fn( x: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int, ::libloading::Error, >, - baz: Result< + pub baz: Result< unsafe extern "C" fn( x: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int, ::libloading::Error, >, + pub bazz: Result< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + ... + ) -> ::std::os::raw::c_int, + ::libloading::Error, + >, } impl TestLib { pub unsafe fn new<P>(path: P) -> Result<Self, ::libloading::Error> @@ -29,15 +36,14 @@ impl TestLib { let __library = ::libloading::Library::new(path)?; let foo = __library.get("foo".as_bytes()).map(|sym| *sym); let baz = __library.get("baz".as_bytes()).map(|sym| *sym); + let bazz = __library.get("bazz".as_bytes()).map(|sym| *sym); Ok(TestLib { - __library: __library, + __library, foo, baz, + bazz, }) } - pub fn can_call(&self) -> CheckTestLib { - CheckTestLib { __library: self } - } pub unsafe fn foo( &self, x: *mut ::std::os::raw::c_void, @@ -53,14 +59,3 @@ impl TestLib { (sym)(x) } } -pub struct CheckTestLib<'a> { - __library: &'a TestLib, -} -impl<'a> CheckTestLib<'a> { - pub fn foo(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.foo.as_ref().map(|_| ()) - } - pub fn baz(&self) -> Result<(), &'a ::libloading::Error> { - self.__library.baz.as_ref().map(|_| ()) - } -} diff --git a/tests/headers/dynamic_loading_with_whitelist.hpp b/tests/headers/dynamic_loading_with_whitelist.hpp index 922b5461..33bfe805 100644 --- a/tests/headers/dynamic_loading_with_whitelist.hpp +++ b/tests/headers/dynamic_loading_with_whitelist.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --dynamic-loading TestLib --whitelist-function baz --whitelist-function foo +// bindgen-flags: --dynamic-loading TestLib --whitelist-function baz --whitelist-function foo --whitelist-function bazz class X { int _x; @@ -13,3 +13,4 @@ class X { int foo(void *x); int bar(void *x); int baz(void *x); +int bazz(int, ...); |