创建链接到锈dylib为R中使用共享的C对象 [英] Create shared C object linked to Rust dylib for use in R

查看:92
本文介绍了创建链接到锈dylib为R中使用共享的C对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个共享对象,我可以加载到R,它将由R的C API的调用方式防锈功能。从C调用生锈,我下面这个博客文章。当我尝试创建共享库,并链接到锈库我的问题就出现了。链接器抱怨它找不到我的防锈功能。我是很新的编译语言,并给予这几天的价值的努力转向SO之前。在这段时间里我学到了很多关于编译器标志和没有来没有接近的解决方案。我想这可能是一些显而易见的。

我的C ++ code:

 的#includeRinternals.h
#包括R.H
#包括treble.h// TEST.CPP
为externC{SEXP三(VAL SEXP){    int32_t IVAL = * INTEGER(VAL);
    Rprintf(9三倍为%d \\ n,高音(IVAL));
    返回R_NilValue;
}}

treble.h:

 的#include< stdint.h>int32_t高音(int32_t值);

我的锈code:

 #![crate_type =dylib]#[no_mangle]
酒馆的extern FN高音(价值:I32) - GT; I32 {
  值* 3
}

这是我做的命令行是什么:

  $ rustc glue.rs
$ G ++ -shared -o TEST.CPP -I test.so /资源库/框架/ R.framework /头-L /库/框架/ R.framework /库-L。 -lR -lglue
适用于建筑x86_64的未定义符号:
  高音(INT),从引用:
      _triple在测试dac64b.o
LD:符号(S)未找到x86_64的架构
铿锵:错误:连接命令,退出code 1(使用-v看看调用)失败

检查对象文件锈创建:

  $纳米-GU libglue.dylib
...
0000000000001750ŧ_treble


解决方案

在C ++ code,你需要声明的防锈功能(它通过C ABI可用)为外部 C

treble.h

 的#include< stdint.h>为externC{
  int32_t高音(int32_t值);
}

您收到此错误是因为C ++编译器的名称重整的方法高音试图反对它链接前。 的externC禁用截断。

此外,你的铁锈FFI code应该总是使用类型从 libc的箱子;你的情况,你想的libc :: int32_t

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

解决方案

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.

这篇关于创建链接到锈dylib为R中使用共享的C对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆