【发布时间】:2018-03-13 11:33:11
【问题描述】:
我正在尝试在 Rust 中构建 Octave 函数。 Octave 的 API 在 C++ 中,所以我使用 rust-bindgen 生成了绑定。我目前正在解决尝试生成bindings that include std::string 时出现的问题。如果我能让它保持不透明且指向C++ std::string 的有效指针,那就太好了。是否可以在我需要传入 C++ std::string 的任何时候在 C++ 端构建实用程序函数?
当我第一次尝试这个时,我很天真。这显然是错误的。 Rust std::ffi:CString 用于 C 字符串,而不是 C++ 字符串。我发现this recent blog 在比较两者时很有帮助。我的第一次尝试看起来like this:
#![allow(non_snake_case)]
#![allow(unused_variables)]
extern crate octh;
// https://thefullsnack.com/en/string-ffi-rust.html
use std::ffi::CString;
#[no_mangle]
pub unsafe extern "C" fn Ghelloworld (shl: *const octh::root::octave::dynamic_library, relative: bool) -> *mut octh::root::octave_dld_function {
let name = CString::new("helloworld").unwrap();
let pname = name.as_ptr() as *const octh::root::std::string;
std::mem::forget(pname);
let doc = CString::new("Hello World Help String").unwrap();
let pdoc = doc.as_ptr() as *const octh::root::std::string;
std::mem::forget(pdoc);
octh::root::octave_dld_function_create(Some(Fhelloworld), shl, pname, pdoc)
}
pub unsafe extern "C" fn Fhelloworld (args: *const octh::root::octave_value_list, nargout: ::std::os::raw::c_int) -> octh::root::octave_value_list {
let list_ptr = ::std::ptr::null_mut();
octh::root::octave_value_list_new(list_ptr);
::std::ptr::read(list_ptr)
}
我需要将函数名称和文档作为字符串传递给octave_dld_function_create。我希望有一个CppString 可以代替我使用。关于如何进行的任何建议?
【问题讨论】:
-
C++ 编译器/stdlib 供应商没有解决这个问题;我不希望 Rust 会。 ;-](需要明确的是,
std::string是一个强制接口,而不是强制实现,如果你想通过值传递任何东西,你至少需要知道它的大小/布局。) -
我正在尝试与 Ubuntu Linux 上的 GNU Octave 互操作。编译器是来自
gcc -dumpversion的gcc 6.3.0,标准库是来自ldconfig -p | grep stdc++的libstdc++.so.6 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libstdc++.so.6。 stackoverflow.com/a/10355215/23059 -
那是定义了
_GLIBCXX_USE_CXX11_ABI还是没有定义? ;-] 重点是,如果它没有在 C++ 构建工具中正确抽象,那么在其他地方这样做的机会非常渺茫。例如。我的系统有可用的 libc++、libstdc++ 和 Dinkumware 标准库。 -
我不知道。我看到在一些 Octave 构建文件中引用了
-lstdc++。我不确定我需要一些抽象的东西。我可以在构建时向 Octave 库添加一个函数。 -
-lstdc++是一个链接器命令,它只暗示一些(共享)目标文件要链接到;因为即使是 C++ 编译器也不知道“std::string是什么?”这个问题的答案,除了你提供给它的源代码。