Rust和C在Visual Studio中的兼容性问题

4

是否可能使用rustc编译创建静态库,并将其链接到使用MSVC编译的可执行文件中?


1
我想这在理论上是可能的;但你必须匹配修饰过的函数名称、调用约定、参数和返回类型。为什么不创建一个dll并在C中构建一个thunk层?这样可能会更加稳定。 - Bathsheba
出于性能原因,我宁愿远离DLL... - Jouan
1
我使用类似以下的代码: typedef jint (JNICALL *PFN_GET)(JavaVM **vmBuf, jsize bufLen, jsize *nVMs); static PFN_GET pfn = NULL; if (pfn == NULL){ pfn = (PFN_GET)GetProcAddress(s_jni_library, "JNI_GetCreatedJavaVMs"); } - Bathsheba
@Bathsheba 啊,我了解了。这似乎比虚函数调用更快,但仍然不如静态函数调用快。您无法进行内联,还需要指针检查的开销和函数指针调用的开销。 - Jouan
如果性能非常关键,那么你将不得不强制使用静态链接。我从未尝试过,但正如我已经说过的,我想这是可能的,只是需要一些痛苦。祝你好运! - Bathsheba
显示剩余3条评论
1个回答

2

如果您想仅使用rustc生成静态库,您需要在crate的lib.rs文件中指定一些属性,并将导出的函数标记为如下:

#![crate_type = "static_lib"]
#![crate_name = "mylib"]

use libc::c_int;

#[no_mangle]
pub extern fn my_exported_func(num: c_int) -> c_int {
    num + 1
}

只需调用rustc lib.rs即可。这适用于所有rustc支持的平台。

在C/C++头文件中添加:

#pragma once

// only use extern block if the header is put inside a C++ CU
extern "C" {
    int my_exported_func(int num);
}

如果需要,将输出的.lib.a链接到代码中。

对于Cargo,请在您的Cargo.toml中指定包类型和名称。

参考资料:


1
请注意,Rust的i32并不一定等同于C语言的int - Francis Gagné
1
请使用 libc::c_int - Chris Morgan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接