gpt4 book ai didi

c++ - 如何从 Rust 调用 C++ 动态库?

转载 作者:行者123 更新时间:2023-11-29 08:10:46 31 4
gpt4 key购买 nike

我想从 Rust 调用 C++ 动态库 (*.so),但我不想从 Rust 构建它。像这样,

cc::Build::new()
    .file("src/foo.cc")
.shared_flag(true)
.compile("libfoo.so");

在某些情况下,我只需要调用几个函数,而不是所有函数。我该如何使用它?

最佳答案

在继续之前,请确保您对 Rust 有基本的了解 FFI (foreign function interface) .

在Rust中,调用C容易,调用C++难。

要在 Rust 中调用 C 函数,您只需将它们用 extern 包装起来, 做一些基本的类型转换,有时 unsafe .

要调用 C++ 函数,由于 Rust 没有内置 C++ 功能知识,您可能需要进行大量手动翻译。例如,这里是来自 Rust-Qt 的文档的一部分:

Many things are directly translated from C++ to Rust:

  • Primitive types are mapped to Rust's primitive types (like bool) and types provided by libc crate (like libc::c_int).
  • Fixed-size numeric types (e.g int8_t or qint8) are mapped to Rust's fixed size types (e.g. i8).
  • Pointers, references and values are mapped to Rust's respective types.
  • C++ namespaces are mapped to Rust submodules.
  • C++ classes and structs are mapped to Rust structs. This also applies to all instantiations of template classes encountered in thelibrary's API, including template classes of dependencies.
  • Free functions are mapped to free functions.
  • Class methods are mapped to structs' implementations.
  • Destructors are mapped to Drop and CppDeletable implementations.
  • Function pointer types are mapped to Rust's equivalent representation. Function pointers with references or class values arenot supported.
  • static_cast and dynamic_cast are available in Rust through corresponding traits.

Names of Rust identifiers are modified according to Rust's namingconventions.

When direct translation is not possible:

  • Contents of each include file of the C++ library are placed into a separate submodule.
  • Method overloading is emulated with wrapping arguments in a tuple and creating a trait describing tuples acceptable by each method.Methods with default arguments are treated in the same way.
  • Single inheritance is translated to Deref and DerefMut implementation, allowing to call base class methods on derivedobjects. When deref coercions are not enough, static_cast should beused to convert from derived to base class.
  • Getter and setter methods are created for each public class field.

Not implemented yet but planned:

  • Translate C++ typedefs to Rust type aliases.
  • Implement operator traits for structs based on C++ operator methods (issue). Operatorsare currently exposed as regular functions with op_ prefix.
  • Implement Debug and Display traits for structs if applicable methods exist on C++ side.
  • Implement iterator traits for collections.
  • Subclassing API (issue).
  • Provide access to a class's public variables (issue).
  • Provide conversion from enums to int and back (used in Qt API).
  • Support C++ types nested into template types, like Class1<T>::Class2.

Not planned to support:

  • Advanced template usage, like types with integer template arguments.
  • Template partial specializations.
  • Template methods and functions.

我的建议是将您的 C++ 库包装为 C 库,然后以官方 FFI 方式调用它,或者使用 rust-bindgen自动进行包装。

如果您仍想在 Rust 中调用 C++,rustcxx似乎是一个方便的工具。

至于库链接,很简单:

  • 将库放入您的系统库搜索路径,如/usr/lib/usr/local/lib/ , 确保可以通过 ldconfig -p 找到它.
  • 或者使用环境变量LD_LIBRARY_PATH在运行 cargo 时指定库所在的路径来自 CLI。

关于c++ - 如何从 Rust 调用 C++ 动态库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52923460/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com