Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

function is marked #[no_mangle], but not exported

Tags:

rust

I have a project with two files:

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

rle.rs contains the following (and much more):

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...)

lib.rs looks like the following:

mod rle;
use rle::rle_new; 
// blablabla

When I load the library in Python I get the error:

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

It seems like Rust understands this (clever, clever) because my linter says:

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

How do I fix this and make my function rle_new available from the target/debug/libranges.dylib file?

The crate-type in my Cargo.toml is ["dylib"]

like image 987
The Unfun Cat Avatar asked Oct 19 '16 12:10

The Unfun Cat


1 Answers

The Rust philosophy is to prefer explicit over implicit.

Rust will only export symbols that are publicly accessible from the root crate. This makes it very easy to inspect the public interface of a crate without crawling through all files: just follow the pub from the root.

In your case, the symbol rle_new is publicly accessible to anyone having access to the rle module (such as sibling modules), but the rle module itself is not publicly accessible in the root crate.

The simplest solution is to selectively export this symbol:

pub use rle::rle_new;
like image 80
Matthieu M. Avatar answered Nov 08 '22 07:11

Matthieu M.