如何在 R 负载表中注册 C 符号?

How can I register C symbols in the R load table?

本文关键字:注册 符号 负载      更新时间:2023-10-16

这不起作用

关于如何在没有 Rcpp 的情况下在 R 中包含 C 和 C++ 代码,有各种手册。按照本手册中的第一个示例编写 c++ 函数

void double_me(int* x) {
// Doubles the value at the memory location pointed to by x
*x = *x + *x;
}

到文件中doubler.cpp和编译

R CMD SHLIB doubler.cpp

工作正常。该过程会导致其他文件doubler.odoubler.so。共享对象可以从 R 加载,但不注册符号double_me它应该公开:

> dyn.load("doubler.so")
> getLoadedDLLs()
Filename
base                                                                    base
methods                           /usr/lib/R/library/methods/libs/methods.so
utils                                 /usr/lib/R/library/utils/libs/utils.so
grDevices                     /usr/lib/R/library/grDevices/libs/grDevices.so
graphics                        /usr/lib/R/library/graphics/libs/graphics.so
stats                                 /usr/lib/R/library/stats/libs/stats.so
doubler                                   /home/<user>/<path>/src/doubler.so
tools                                 /usr/lib/R/library/tools/libs/tools.so
Dynamic.Lookup
base                        FALSE
methods                     FALSE
utils                       FALSE
grDevices                   FALSE
graphics                    FALSE
stats                       FALSE
doubler                      TRUE
tools                       FALSE
>  getDLLRegisteredRoutines("doubler")
data frame with 0 columns and 0 rows

因此

> .C("double_me", as.integer(1))
Error in .C("double_me") : C symbol name "double_me" not in load table

显然,缺少一些东西 - 大概是加载表中符号(函数名称)的注册。

这有效,但很难理解,如何

根据本手册,我们应该应用

extern "C" {
}

到另一个文件中的第三个函数。在手册中,这是一个X_main.o函数,与加载的库(X.so)一起编译,显然是在加载表中注册的,而从未被显式加载。然后仍然可以用.C("X_main")调用它。

我不确定这究竟是如何工作的,或者如何将其应用于具有微不足道double_me函数的第一个示例。

相关问题

在Stackoverflow上有很多问题可能与此有关。 不幸的是,他们都没有一个解释清楚的答案。例子是这个,这个,这个和这个。

C++允许重载,您可以在其中使用具有不同参数的相同函数。为了实现这一点,它们必须在编译文件中具有不同的名称。因此,当您将void double_me(int* x)声明为C++函数时,它实际上将被编译为名称上带有可怕后缀的内容。有关详细信息,请参阅示例 https://sourceware.org/binutils/docs/binutils/c_002b_002bfilt.html。如果指定 C 链接,则不会发生名称重整,并且它会以相当正常的名称获得输出。

回到你的问题,你想从R调用的函数可能应该有C链接。就是这样。您对需要第三个功能等感到困惑。只要double_me标记为外部"C",你就会一切都好起来的。

即使如此,您可能需要向 R 注册函数.....