summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/dyngen.rs63
-rw-r--r--src/codegen/mod.rs8
-rw-r--r--tests/expectations/tests/dynamic_loading_simple.rs25
-rw-r--r--tests/expectations/tests/dynamic_loading_template.rs20
-rw-r--r--tests/expectations/tests/dynamic_loading_with_blacklist.rs20
-rw-r--r--tests/expectations/tests/dynamic_loading_with_class.rs20
-rw-r--r--tests/expectations/tests/dynamic_loading_with_whitelist.rs29
-rw-r--r--tests/headers/dynamic_loading_with_whitelist.hpp3
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, ...);