nagisa / rust_libloading

Bindings around the platform's dynamic library loading primitives with greatly improved memory safety.
https://docs.rs/libloading
ISC License
1.24k stars 102 forks source link

Is possible to load C++ class? I got an `undefined symbol` error when trying this. #115

Closed mojerro closed 1 year ago

mojerro commented 1 year ago

I'm trying to load c++ class using this, but it's hard for me to finish it.

fn main() {
    let res = call_dynamic();

    println!("Hello, world! {:?}", res);
}

fn call_dynamic() -> Result<char, Box<dyn std::error::Error>> {
    unsafe {
        let lib = libloading::Library::new("./lib/thosttraderapi_se.so")?;
        let func: libloading::Symbol<unsafe extern "C" fn() -> char> = lib.get(b"CThostFtdcTraderApi::GetApiVersion()")?;
        Ok(func())
    }
}

nm -g --defined-only -C mylib.so

00000000001c238a T CThostFtdcTraderApi::GetApiVersion()
00000000001c2342 T CThostFtdcTraderApi::CreateFtdcTraderApi(char const*)
00000000001d1b8e W CThostFtdcTraderApi::CThostFtdcTraderApi()
00000000001d1b8e W CThostFtdcTraderApi::CThostFtdcTraderApi()
00000000001caadc W CThostFtdcTraderApi::~CThostFtdcTraderApi()
00000000001caadc W CThostFtdcTraderApi::~CThostFtdcTraderApi()
nagisa commented 1 year ago

It is possible. Given your code/nm output, it does seem like the symbol you’re attempting to load is mangled, and nm is demangling it for you. libloading does not automatically mangle or demangle symbols for you as described in the documentation for Library::get. What you want is probably gonna start with a _Z and will never contain ::. Invoke nm --no-demangle to get actual symbols that are usable with libloading.

Make sure that the calling convention used on the C++ side and on the Rust side match.

Hope you can get it to work :)

mojerro commented 1 year ago

o, I got it, I need to run nm -g --defined-only mylib.so to let it work