函数标记为#[no_mangle],但未导出

The*_*Cat 6 rust

我有一个包含两个文件的项目:

  • src/lib.rs
  • src/rle.rs

rle.rs 包含以下(以及更多):

extern crate libc;

#[derive(Debug, PartialEq)]
pub struct Rle {
    pub lengths: Vec<i32>,
    pub values: Vec<i32>,
}

#[no_mangle]
pub extern "C" fn rle_new(blablabla...)
Run Code Online (Sandbox Code Playgroud)

lib.rs 看起来如下:

mod rle;
use rle::rle_new; 
// blablabla
Run Code Online (Sandbox Code Playgroud)

当我在Python中加载库时,我收到错误:

Traceback (most recent call last):
  File "compact_ranges.py", line 19, in <module>
    lib.rle_new.restype = POINTER(RleS)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 378, in __getattr__
    func = self.__getitem__(name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 383, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x7f94ca700370, rle_new): symbol not found
Run Code Online (Sandbox Code Playgroud)

看起来Rust理解这一点(聪明,聪明),因为我的linter说:

17   1 warning         function rle_new is marked #[no_mangle], but not exported, #[warn(private_no_mangle_fns)] on by default (rust-cargo)
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题并使我的函数rle_new从target/debug/libranges.dylib文件中可用?

crate-type在我的Cargo.tomlIS["dylib"]

Mat*_* M. 15

Rust哲学更倾向于明确而非隐含.

Rust将仅导出可从根包中公开访问的符号.这使得检查包的公共接口非常容易,而无需遍历所有文件:只需pub从根目录开始.

在您的情况下,rle_new任何有权访问该rle模块的人(例如兄弟模块)都可以公开访问该符号,但该rle模块本身不能在根条箱中公开访问.

最简单的解决方案是有选择地导出此符号:

pub use rle::rle_new;
Run Code Online (Sandbox Code Playgroud)