Rcpp:如何从Rcpp包中调用C函数

3
我想使用Rcpp编写一个C++函数,该函数使用包“hypred”中的C函数。该包可以在CRAN这里找到。
我阅读了在Rcpp中使用其他包中的C函数,但不确定是否适用于我的情况,如果适用,则该怎么做。
所需函数位于源文件/src/hypredRoutines.c中,名称为meiosisFUNAllChr
基于此SO问题,我所做的是:
  1. I separated the function meiosisFUNAllChr from the rest of the code and placed it in a new file called meiosisFUNAllChr.c.
  2. I created a header file called meiosisFUNAllChr.h containing:

    #ifndef MEIOSISFUNALLCHR_H
    #define MEIOSISFUNALLCHR_H
    void meiosisFUNallChr (...);
    #endif 
    
  3. Compiled it with

    gcc -c -o meiosisFUNAllChr.o meiosisFUNAllChr.c
    
  4. Created a dummy c++ function

    #include <Rcpp.h>
    using namespace Rcpp;
    
    extern "C" {
     #include "meiosisFUNallChr.h"
    }
    
    // [[Rcpp::export]]
    int timesTwo(int x) {
     return x * 2;
    }
    

目前,使用sourceCpp编译不起作用。你能告诉我如何让它工作吗?

非常感谢!

编辑

使用sourceCpp编译会出现以下错误:

meiosisFUNallChr.h: file or directory not found

我知道这些设施并且已经使用过它们,但我不知道这将如何帮助我使C函数在我的代码中正常工作 :-) - NoBackingDown
你尝试过使用 sourceCpp 吗? - Dominic Comtois
好的...当你说它不起作用时,你得到了什么?一个错误消息?还是这个函数根本不可用? - Dominic Comtois
@DominicComtois 我已在编辑中包含了它。 - NoBackingDown
@DominicComtois 我正在引用 .cpp 文件。 - NoBackingDown
显示剩余4条评论
2个回答

3

hypred注册了两个函数,你可以在R级别获取你想要的函数,例如:

xp <- getDLLRegisteredRoutines( getLoadedDLLs()[["hypred"]] )[[".C"]][["meiosisFUNallChr"]]$address

我相信你可以像这样在C++中访问函数指针:
DL_FUNC meiosisFUNallChr = reinterpret_cast<DL_FUNC>( R_ExternalPtrAddr(xp) ) ;

但是如果你能说服软件包的作者,实现这个方案,那么直接调用C函数可能会更好。


关于注册方案的+1 -- 在Rcpp宇宙中有一些包可以做到这一点。 我最简单的可能是RApiSerialize。@romain:getDLLRegisteredRoutine(...)方法是否被CRAN“祝福”(或至少被容忍),即您是否在mlxR中使用了它? - Dirk Eddelbuettel
我不知道。但我认为应该没有问题,因为我只调用了允许的 R 函数 getDLLRegisteredRoutinesgetLoadedDLLs ... mlxR 是完全不同类型的东西。 - Romain Francois
是的,这是一只完全不同的鸟——不是R控制下的库。你所做的事情是否有可推广性?我们在Rblpapi中可能会遇到类似的问题。 - Dirk Eddelbuettel
我们使用的可能不太适合分发。实际上,几乎没有任何代码或示例直接引用底层的C++库。用户应该先安装一些软件,然后mlxR在运行时从该软件编译一个R包,因此CRAN不需要知道该软件的存在... - Romain Francois

-1
简而言之:
  • 您想使用另一个源文件(可能在适当的许可下可用)。

  • 您想从您的新文件中调用它。

  • 所以您已经有了两个文件。

现在警报应该响起来,因为您真的非常想创建一个包

Rcpp文档在许多地方详细介绍了这一点。CRAN上有340多个使用Rcpp的软件包,其中许多都涉及到调用C文件的问题。选择一两个,研究它们的结构;还可以选择由完全记录的Rcpp工具创建的一个或两个软件包,例如Rcpp.package.skeleton(),这样就会变得更加清晰。

编辑:显然,只有在其他软件包没有导出其函数时才需要采取此方法。如果您可以让作者导出,那么请按照Romain的答案进行操作。导出/使用的软件包对有zoo/xts、xts/RcppXts、expm/RcppKalman(不在CRAN上)、RApiSerialize/RcppRedis等。


谢谢Dirk,我会按照你的建议去做。 - NoBackingDown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接