5

I'm trying to use a Rust code in C. I used no mangle for Rust and extern "C" for C++ code that is going to be defined in Rust. However I keep getting undefined references whem trying to link my Rust library into my C++ code

interface.rs

use std::os::raw::{c_int};
type OnDataCallback = unsafe extern "C" fn(data: *mut u8, len: usize) -> c_int;

static mut onDataCallback_: Option<OnDataCallback> = None;

#[no_mangle]
pub extern "C" fn registerOnDataCallback(cb: Option<OnDataCallback>) -> c_int
{
    unsafe{onDataCallback_ = cb;}
    return 0;
}

#[no_mangle]
pub extern "C" fn doSomething()
{

    let mut s = String::from("hello world\0");
    unsafe {
        unsafe{onDataCallback_.unwrap()(s.as_mut_ptr() , 100)};
    }
}

interface.cpp

#include <iostream>

typedef int (*onDataCallback_)(uint8_t *data, size_t len);

extern "C" int registerOnDataCallback(onDataCallback_ cb);

extern "C" void doSomething();

extern "C" int onDataCallback(uint8_t *data, size_t len) {
    std::cout << "called onData with size " + len << std::endl;
}

int main() {
    registerOnDataCallback(&onDataCallback);
    doSomething();
    getchar();
    return 0;
}

How I'm compiling:

rustc --crate-type=staticlib interface.rs
g++ -o rust_c -L. -linterface interface.cpp

Error:

/tmp/ccgjsC7i.o: In function `main':
interface.cpp:(.text+0x51): undefined reference to `registerOnDataCallback'
interface.cpp:(.text+0x56): undefined reference to `doSomething'
collect2: error: ld returned 1 exit status

I've followed 2 different tutorials. I also tried with Cargo:

[package]
name = "smoltcp_c_interface"
version = "0.1.0"

[lib]
name = "smoltcp_c_interface"
path = "interface.rs"
crate-type = ["staticlib"]

[dependencies]
libc = "0.2.0"

then did cargo build and tried to link with the g++ in the same way as above. Same undefined references.

0

1 Answer 1

9

Linker searches for symbols from left to right. Specify the library with symbols after the source file that needs them.

g++ -o rust_c -L. interface.cpp -linterface

Then add rust dependencies - -pthread and dlsym -ldl.

Sign up to request clarification or add additional context in comments.

1 Comment

The reason for this behavior is that this allows the linker to only care about the symbols required rather than having to make a map of all known symbols. Thus the linker builds a set of required-but-not-seen symbols as it goes: adding required symbols, and removing satisfied requirements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.