Create shared C object linked to Rust dylib for use in R

戏子无情 提交于 2019-12-22 09:57:16

问题


I am trying to create a shared object I can load into R that calls Rust functions by way of R's C API. To call Rust from C, I am following this blog post. My problem arises when I try to create the shared library and link to the Rust library. The linker complains that it can't find my Rust function. I am quite new to compiled languages and have given this a couple days' worth of effort before turning to SO. In that time I have learned a lot about compiler flags and yet come no closer to a solution. I think it may be something obvious.

My C++ code:

#include "Rinternals.h"
#include "R.h"
#include "treble.h"

// test.cpp
extern "C" {

SEXP triple(SEXP val) {

    int32_t ival = *INTEGER(val);
    Rprintf("9 tripled is %d\n", treble(ival));
    return R_NilValue;
}

}

treble.h:

#include <stdint.h>

int32_t treble(int32_t value);

My Rust code:

#![crate_type = "dylib"]

#[no_mangle]
pub extern fn treble(value: i32) -> i32 {
  value * 3
}

This is what I'm doing on the command line:

$ rustc glue.rs
$ g++ -shared test.cpp -o test.so -I/Library/Frameworks/R.framework/Headers -L/Library/Frameworks/R.framework/Libraries -L. -lR -lglue
Undefined symbols for architecture x86_64:
  "treble(int)", referenced from:
      _triple in test-dac64b.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Inspecting the object file that rust creates:

$ nm -gU libglue.dylib
...
0000000000001750 T _treble

回答1:


In the C++ code, you need to declare the Rust function (which is available via the C ABI) as extern "C".

treble.h

#include <stdint.h>

extern "C" {
  int32_t treble(int32_t value);
}

The error you are getting is because the C++ compiler is name mangling the method treble before attempting to link against it. extern "C" disables the mangling.

Additionally, your Rust FFI code should always use the types from the libc crate; in your case you want libc::int32_t.



来源:https://stackoverflow.com/questions/30904870/create-shared-c-object-linked-to-rust-dylib-for-use-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!