已经通过测试了, 但需要注意的是 rust 不支持导出符号参数信息,也就是说 labview 不能直接识别到参数返回类型,需要你手动输入, 官方的 issue 三年了仍未解决
最近有个老项目上位机与 PLC 的通信出了问题,解决办法说是给个上传 FTP 的动态库他那边用 Labview 调用,组长是准备 C++ 来写,搞了半天那边又说是得 32 位… 我想到 rust 也能生产动态库,就用 rust 写了个动态库,用 C 来调用没什么问题,但不知道 Labview 调用怎么样,写篇博客记录一下动态库生成的一些注意事项
基本步骤
建立 lib 模式的 rust 项目
修改 cargo.toml 中 lib 节点
[package] name = "bindc" version = "0.1.0" edition = "2021" [dependencies] [lib] crate-type = ["cdylib"]
编写代码
use std::ffi::c_char; #[no_mangle] pub extern "C" fn add(left: *const c_char, right: *const c_char) -> *const c_char { let left = unsafe { std::ffi::CStr::from_ptr(left).to_str().unwrap() }; let right = unsafe { std::ffi::CStr::from_ptr(right).to_str().unwrap() }; let combined = format!("{}{}", left, right); let result = std::ffi::CString::new(combined).unwrap(); result.into_raw() }
编译,获得
xxx.dll
和xxx.dll.lib
xxx.dll.lib
放到源代码目录,并引入:target_link_libraries(calculatorform PUBLIC Qt::Core Qt::Gui Qt::Widgets "${CMAKE_SOURCE_DIR}/bindc.dll.lib" )
xxx.dll
放到执行文件目录下,便能够正常运行了
注意事项
- 可以使用 cbindgen 库来生成头文件,这样就不用自己手写声明了
- 导出的函数返回简化,最后是用 int 来记录返回情况,对于错误转出对应 code
- rust 导出的动态库是 C 的绑定,C++ 中使用需要用
extern "C"
来声明