Skip to content

Commit

Permalink
feat: add dynamic loading of variable
Browse files Browse the repository at this point in the history
  • Loading branch information
discord9 authored and emilio committed Apr 23, 2024
1 parent 5260c91 commit 9eb512e
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 5 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -0,0 +1,4 @@
// bindgen-flags: --dynamic-loading TestLib --dynamic-link-require-all

int foo;
int *baz;
4 changes: 4 additions & 0 deletions bindgen-tests/tests/headers/dynamic_loading_variable_simple.h
@@ -0,0 +1,4 @@
// bindgen-flags: --dynamic-loading TestLib

int foo;
int *baz;
@@ -0,0 +1,5 @@
// bindgen-flags: --dynamic-loading TestLib --allowlist-var foo --allowlist-var bar

int foo;
int bar;
int baz; // should not be allowed
47 changes: 45 additions & 2 deletions bindgen/codegen/dyngen.rs
@@ -1,7 +1,7 @@
use crate::codegen;
use crate::ir::context::BindgenContext;
use crate::ir::function::ClangAbi;
use proc_macro2::Ident;
use proc_macro2::{Ident, TokenStream};

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

#[allow(clippy::too_many_arguments)]
pub(crate) fn push(
pub(crate) fn push_func(
&mut self,
ident: Ident,
abi: ClangAbi,
Expand Down Expand Up @@ -196,4 +196,47 @@ impl DynamicItems {
#ident
});
}

pub fn push_var(
&mut self,
ident: Ident,
ty: TokenStream,
is_required: bool,
) {
let member = if is_required {
quote! { *mut #ty }
} else {
quote! { Result<*mut #ty, ::libloading::Error> }
};

self.struct_members.push(quote! {
pub #ident: #member,
});

let deref = if is_required {
quote! { self.#ident }
} else {
quote! { *self.#ident.as_ref().expect("Expected variable, got error.") }
};
self.struct_implementation.push(quote! {
pub unsafe fn #ident (&self) -> *mut #ty {
#deref
}
});

let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
self.constructor_inits.push(if is_required {
quote! {
let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym)?;
}
} else {
quote! {
let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym);
}
});

self.init_fields.push(quote! {
#ident
});
}
}
16 changes: 13 additions & 3 deletions bindgen/codegen/mod.rs
Expand Up @@ -53,7 +53,7 @@ use crate::ir::ty::{Type, TypeKind};
use crate::ir::var::Var;

use proc_macro2::{Ident, Span};
use quote::TokenStreamExt;
use quote::{ToTokens, TokenStreamExt};

use crate::{Entry, HashMap, HashSet};
use std::borrow::Cow;
Expand Down Expand Up @@ -799,7 +799,17 @@ impl CodeGenerator for Var {
}
);

result.push(tokens);
if ctx.options().dynamic_library_name.is_some() {
result.dynamic_items().push_var(
canonical_ident,
self.ty()
.to_rust_ty_or_opaque(ctx, &())
.into_token_stream(),
ctx.options().dynamic_link_require_all,
);
} else {
result.push(tokens);
}
}
}
}
Expand Down Expand Up @@ -4576,7 +4586,7 @@ impl CodeGenerator for Function {
let args_identifiers =
utils::fnsig_argument_identifiers(ctx, signature);
let ret_ty = utils::fnsig_return_ty(ctx, signature);
result.dynamic_items().push(
result.dynamic_items().push_func(
ident,
abi,
signature.is_variadic(),
Expand Down

0 comments on commit 9eb512e

Please sign in to comment.