【发布时间】:2021-02-13 04:11:05
【问题描述】:
编辑:经过一番研究,我找到了部分解决方案。 link_name attribute 可用于更改为外部变量链接的名称。我现在的问题是 bindgen 是否可以自动应用此属性来解决链接错误。背景:
我正在尝试让我的 Rust 项目与 Julia 的 C 库一起工作。我将原来的错误缩减为这段代码:
// main.rs
extern "C" {
pub static mut jl_method_type: *mut ();
}
fn main() {
println!("{:?}", unsafe { jl_method_type });
}
// build.rs
fn main() {
println!("cargo:rustc-link-search=C:/path/to/julia/lib/");
println!("cargo:rustc-link-lib=julia");
}
(我还必须将文件 libjulia.dll.a 重命名为 julia.lib 以便链接器可以找到它。)
产生的错误如下:
note: reprod.jth9vslxkrhc6ez.rcgu.o : error LNK2019:
unresolved external symbol jl_method_type referenced
in function _ZN1reprod4main17hf5ae7fcf7e25b2b0E
为了尝试进一步精简,我在 C++ 中复制了它:
// Compile with clang -ljulia -LC:/path/to/julia/lib/ test.cpp -IC:/path/to/julia/include/julia/
extern "C" void* jl_method_type;
int main() {
auto local = jl_method_type;
return 0;
}
这会产生与以前相同的错误。然后我找到this SO question 并意识到我需要像这样修改定义:
extern "C" __declspec(dllimport) void* jl_method_type;
然后编译 C++ 程序没有任何错误。但是,我找不到 Rust 的等价物。
一些附加说明,我用来与 Julia 交互的实际代码使用 bindgen 为 DLL 生成 Rust 绑定。据我从链接器错误中可以看出,它们可以正常使用 DLL 定义的函数,但在尝试访问全局变量时会失败。这与链接问题中的问题一致,其中添加 __declspec() 在函数上是可选的,但在变量上是必需的。
编辑:我发现使用名称 __impl_jl_method_type 而不使用 __declspec(dllimport) 注释会导致链接成功。这也适用于 Rust 代码。但是,由于我使用的实际代码是由 bindgen 生成的,因此缺少此前缀。该代码还被提供绑定绑定的安全包装器的 crate 使用,因此似乎应该有一种方法可以让所有内容正确链接,而无需根据平台更改变量名称。
【问题讨论】: