[英]Unable to get result of std::string function in C++ to C# Interop
[英]Rust interop with C++ std::string
我正在尝试在Rust中构建Octave函数。 Octave的API是用C ++编写的,所以我使用了rust-bindgen生成了绑定。 我正在解决尝试生成包含std::string
绑定时出现的问题。 如果我可以将它指向C ++ std::string
opaque和有效指针,那就太好了。 是否有可能在我需要传递C ++ std::string
时在C ++端构建实用程序函数?
当我第一次尝试这个时,我很天真。 这显然是错误的。 Rust std::ffi:CString
用于C字符串,而不是C ++字符串。 我发现这篇最近的博客在比较两者时很有帮助。 我的第一次尝试看起来像这样 :
#![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
。 有关如何进行的任何建议?
这是一个经典的FFI问题,解决方案是使用“沙漏”设计:语言A <=> Common ABI <=>语言B.
当然,有可能进化bindgen以便它可以忠实地再现C ++ ABI,但实际上它需要一个完整的C ++编译器,这可能是太多的努力。
使用“沙漏”设计,每种具有困难ABI的语言都使用他们自己的专用工具链转换为特定的着名ABI。 在这种情况下,它将是C ++ <=> C <=> Rust。
一种可能的解决方案是围绕C ++ API创建一个C包装器库,然后在其上使用bindgen。 这就是LLVM和Clang项目的作用。
这是最简单的解决方案,Octavo项目可能非常愿意在树中集成这样的octavo-c门面(这总是最好的保证它是最新的)。
另一个解决方案是为bindgen创建一个C ++伴随库,它负责为常见的C ++类型(例如std::string
)提供C-ABI。 这将是一项更加困难的工作,特别是因为:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.