使用 Rcpp 将目标文件 link 转换为函数的简化示例
Simplified example using Rcpp to link an object file to a function
我现有的 C 代码由三个文件组成:头文件(“.h”文件)、库文件(“.o”文件)和源文件。它们目前在 UNIX 下 运行 并在 Matlab 中编译 "mex files"。我想使用 Rcpp 将它们移植到 R。它们又长又复杂,所以我做了一个最小的例子来帮助我理解如何将它们移植到 R。
简化的头文件(my_header.h)是:
typedef unsigned int ui4;
ui4 add_one( ui4 );
简化的 "library" 文件 (my_lib.cpp) 是:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "my_header.h"
ui4 add_one(ui4 x) {
return(x+1);
}
简化后的功能程序(my_program.cpp)为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <Rcpp.h>
#include <cmath>
#include "my_header.h"
using namespace Rcpp;
// [[Rcpp::export]]
ui4 my_program_r () {
//int main (int argc, const char * argv[]) {
//
// As a MATLAB mex file, this function calls "main(..."
//
ui4 value = add_one( (ui4)1 );
printf( "%d", value );
return value;
}
从终端(我在 Mac 上),我可以编译这些而不会出错:
$ g++ my_lib.cpp -c -o my_lib.o
$ g++ my_program.cpp -o my_program my_lib.o
当我尝试在 RStudio 中编译它们时,我得到:
> library(Rcpp)
> sourceCpp( "my_program.cpp" )
Warning message:
In sourceCpp("my_program.cpp") :
No Rcpp::export attributes or RCPP_MODULE declarations found in source
>
为什么不在 Rcpp 下编译?如何在 "sourceCpp" 命令中指定链接文件(“.o”库文件)?需要指定头文件吗?
sourceCpp
命令仅适用于单个文件。如果你有多个文件,你必须使用一个包:
- 调用
Rcpp::Rcpp.package.skeleton(...)
创建骨架包。
- 将
*.h
、*.c
和 *.cpp
复制到 src
文件夹。
- 呼叫
Rcpp::compileAtrributes()
.
- 使用
R CMD build ...
、R CMD check ...
和R CMD INSTALL ...
构建、检查和编译包。 (check
会抱怨未记录的函数...)
有关详细信息,请参阅 Rcpp-package vignette and for example this question。顺便说一句,由于 R 没有 unsigned int
类型,我不确定您的 return 值是否有效。您可能必须切换到 int
或 double
。我也收到了与您不同的错误消息:
Error in dyn.load("/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so") :
unable to load shared object '/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so':
/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so: undefined symbol: _Z7add_onej
你确定上面的代码正是你使用的吗?
我现有的 C 代码由三个文件组成:头文件(“.h”文件)、库文件(“.o”文件)和源文件。它们目前在 UNIX 下 运行 并在 Matlab 中编译 "mex files"。我想使用 Rcpp 将它们移植到 R。它们又长又复杂,所以我做了一个最小的例子来帮助我理解如何将它们移植到 R。
简化的头文件(my_header.h)是:
typedef unsigned int ui4;
ui4 add_one( ui4 );
简化的 "library" 文件 (my_lib.cpp) 是:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "my_header.h"
ui4 add_one(ui4 x) {
return(x+1);
}
简化后的功能程序(my_program.cpp)为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <Rcpp.h>
#include <cmath>
#include "my_header.h"
using namespace Rcpp;
// [[Rcpp::export]]
ui4 my_program_r () {
//int main (int argc, const char * argv[]) {
//
// As a MATLAB mex file, this function calls "main(..."
//
ui4 value = add_one( (ui4)1 );
printf( "%d", value );
return value;
}
从终端(我在 Mac 上),我可以编译这些而不会出错:
$ g++ my_lib.cpp -c -o my_lib.o
$ g++ my_program.cpp -o my_program my_lib.o
当我尝试在 RStudio 中编译它们时,我得到:
> library(Rcpp)
> sourceCpp( "my_program.cpp" )
Warning message:
In sourceCpp("my_program.cpp") :
No Rcpp::export attributes or RCPP_MODULE declarations found in source
>
为什么不在 Rcpp 下编译?如何在 "sourceCpp" 命令中指定链接文件(“.o”库文件)?需要指定头文件吗?
sourceCpp
命令仅适用于单个文件。如果你有多个文件,你必须使用一个包:
- 调用
Rcpp::Rcpp.package.skeleton(...)
创建骨架包。 - 将
*.h
、*.c
和*.cpp
复制到src
文件夹。 - 呼叫
Rcpp::compileAtrributes()
. - 使用
R CMD build ...
、R CMD check ...
和R CMD INSTALL ...
构建、检查和编译包。 (check
会抱怨未记录的函数...)
有关详细信息,请参阅 Rcpp-package vignette and for example this question。顺便说一句,由于 R 没有 unsigned int
类型,我不确定您的 return 值是否有效。您可能必须切换到 int
或 double
。我也收到了与您不同的错误消息:
Error in dyn.load("/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so") : unable to load shared object '/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so': /tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so: undefined symbol: _Z7add_onej
你确定上面的代码正是你使用的吗?