Skip to content

Commit 9eb512e

Browse files
discord9emilio
authored andcommitted
feat: add dynamic loading of variable
1 parent 5260c91 commit 9eb512e

8 files changed

+165
-5
lines changed

bindgen-tests/tests/expectations/tests/dynamic_loading_variable_required.rs

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/dynamic_loading_variable_simple.rs

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/dynamic_loading_variable_with_allowlist.rs

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// bindgen-flags: --dynamic-loading TestLib --dynamic-link-require-all
2+
3+
int foo;
4+
int *baz;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// bindgen-flags: --dynamic-loading TestLib
2+
3+
int foo;
4+
int *baz;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// bindgen-flags: --dynamic-loading TestLib --allowlist-var foo --allowlist-var bar
2+
3+
int foo;
4+
int bar;
5+
int baz; // should not be allowed

bindgen/codegen/dyngen.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::codegen;
22
use crate::ir::context::BindgenContext;
33
use crate::ir::function::ClangAbi;
4-
use proc_macro2::Ident;
4+
use proc_macro2::{Ident, TokenStream};
55

66
/// Used to build the output tokens for dynamic bindings.
77
#[derive(Default)]
@@ -122,7 +122,7 @@ impl DynamicItems {
122122
}
123123

124124
#[allow(clippy::too_many_arguments)]
125-
pub(crate) fn push(
125+
pub(crate) fn push_func(
126126
&mut self,
127127
ident: Ident,
128128
abi: ClangAbi,
@@ -196,4 +196,47 @@ impl DynamicItems {
196196
#ident
197197
});
198198
}
199+
200+
pub fn push_var(
201+
&mut self,
202+
ident: Ident,
203+
ty: TokenStream,
204+
is_required: bool,
205+
) {
206+
let member = if is_required {
207+
quote! { *mut #ty }
208+
} else {
209+
quote! { Result<*mut #ty, ::libloading::Error> }
210+
};
211+
212+
self.struct_members.push(quote! {
213+
pub #ident: #member,
214+
});
215+
216+
let deref = if is_required {
217+
quote! { self.#ident }
218+
} else {
219+
quote! { *self.#ident.as_ref().expect("Expected variable, got error.") }
220+
};
221+
self.struct_implementation.push(quote! {
222+
pub unsafe fn #ident (&self) -> *mut #ty {
223+
#deref
224+
}
225+
});
226+
227+
let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
228+
self.constructor_inits.push(if is_required {
229+
quote! {
230+
let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym)?;
231+
}
232+
} else {
233+
quote! {
234+
let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym);
235+
}
236+
});
237+
238+
self.init_fields.push(quote! {
239+
#ident
240+
});
241+
}
199242
}

bindgen/codegen/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use crate::ir::ty::{Type, TypeKind};
5353
use crate::ir::var::Var;
5454

5555
use proc_macro2::{Ident, Span};
56-
use quote::TokenStreamExt;
56+
use quote::{ToTokens, TokenStreamExt};
5757

5858
use crate::{Entry, HashMap, HashSet};
5959
use std::borrow::Cow;
@@ -799,7 +799,17 @@ impl CodeGenerator for Var {
799799
}
800800
);
801801

802-
result.push(tokens);
802+
if ctx.options().dynamic_library_name.is_some() {
803+
result.dynamic_items().push_var(
804+
canonical_ident,
805+
self.ty()
806+
.to_rust_ty_or_opaque(ctx, &())
807+
.into_token_stream(),
808+
ctx.options().dynamic_link_require_all,
809+
);
810+
} else {
811+
result.push(tokens);
812+
}
803813
}
804814
}
805815
}
@@ -4576,7 +4586,7 @@ impl CodeGenerator for Function {
45764586
let args_identifiers =
45774587
utils::fnsig_argument_identifiers(ctx, signature);
45784588
let ret_ty = utils::fnsig_return_ty(ctx, signature);
4579-
result.dynamic_items().push(
4589+
result.dynamic_items().push_func(
45804590
ident,
45814591
abi,
45824592
signature.is_variadic(),

0 commit comments

Comments
 (0)