我正在尝试编写实现棋盘游戏的R包。我想使用相互引用的类(例如,一块板上有空格,空格上有碎片)。但是,当我尝试构建程序包时,出现以下错误。
==> R CMD INSTALL --no-multiarch --with-keep.source testpkg
clang++ -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I"/Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rcpp/include" -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include -fPIC -Wall -g -O2 -c Family.cpp -o Family.o
* installing to library ‘/Library/Frameworks/R.framework/Versions/3.6/Resources/library’
* installing *source* package ‘testpkg’ ...
** using staged installation
** libs
clang++ -std=gnu++11 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o testpkg.so Chicken.o Family.o RcppExports.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
ld: warning: text-based stub file /System/Library/Frameworks//CoreFoundation.framework/CoreFoundation.tbd and library file /System/Library/Frameworks//CoreFoundation.framework/CoreFoundation are out of sync. Falling back to library file for linking.
installing to /Library/Frameworks/R.framework/Versions/3.6/Resources/library/00LOCK-testpkg/00new/testpkg/libs
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for ‘testpkg’ in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object '/Library/Frameworks/R.framework/Versions/3.6/Resources/library/00LOCK-testpkg/00new/testpkg/libs/testpkg.so':
dlopen(/Library/Frameworks/R.framework/Versions/3.6/Resources/library/00LOCK-testpkg/00new/testpkg/libs/testpkg.so, 6): Symbol not found: __ZN7ChickenC1Ei
Referenced from: /Library/Frameworks/R.framework/Versions/3.6/Resources/library/00LOCK-testpkg/00new/testpkg/libs/testpkg.so
Expected in: flat namespace
in /Library/Frameworks/R.framework/Versions/3.6/Resources/library/00LOCK-testpkg/00new/testpkg/libs/testpkg.so
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/Library/Frameworks/R.framework/Versions/3.6/Resources/library/testpkg’
* restoring previous ‘/Library/Frameworks/R.framework/Versions/3.6/Resources/library/testpkg’
Exited with status 1.
我在下面附上了一个可复制的示例。为了给出一个更简单的示例,这是尝试实现包含Chicken对象的Flock对象。
# testpkg-package.R
## usethis namespace: start
#' @useDynLib testpkg, .registration = TRUE
## usethis namespace: end
NULL
## usethis namespace: start
#' @import Rcpp
## usethis namespace: end
NULL
#zzz.R
#' @useDynLib testpkg
NULL
# Rcpp::loadModule("double_cpp", TRUE)
Rcpp::loadModule("chicken_cpp", TRUE)
Rcpp::loadModule("flock_cpp", TRUE)
// RcppExports.cpp
// Generated by using Rcpp::compileAttributes() -> do not edit by hand
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
#include <Rcpp.h>
using namespace Rcpp;
RcppExport SEXP _rcpp_module_boot_chicken_cpp();
RcppExport SEXP _rcpp_module_boot_flock_cpp();
static const R_CallMethodDef CallEntries[] = {
{"_rcpp_module_boot_chicken_cpp", (DL_FUNC) &_rcpp_module_boot_chicken_cpp, 0},
{"_rcpp_module_boot_flock_cpp", (DL_FUNC) &_rcpp_module_boot_flock_cpp, 0},
{NULL, NULL, 0}
};
RcppExport void R_init_testpkg(DllInfo *dll) {
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
}
// Chicken.h
#include <Rcpp.h>
using namespace Rcpp;
class Chicken {
private:
int id;
public:
Chicken(int n);
};
// Chicken.cpp
#include <Rcpp.h>
using namespace Rcpp;
class Chicken {
private:
int id;
public:
Chicken(int n){
id = n;
}
};
RCPP_EXPOSED_CLASS(Chicken)
RCPP_MODULE(chicken_cpp) {
class_<Chicken>("Chicken")
.constructor<int>()
;
}
// Family.cpp
#include <Rcpp.h>
#include <vector>
#include "Chicken.h"
using namespace Rcpp;
class Flock {
private:
std::string breed;
std::vector<Chicken> chickens;
public:
Flock(std::string b){
breed = b;
for(int i=0; i<10; i++){
Chicken newChicken = Chicken(i);
chickens.push_back(newChicken);
}
}
};
RCPP_EXPOSED_CLASS(Flock)
RCPP_MODULE(flock_cpp) {
class_<Flock>("Flock")
.constructor<std::string>()
;
}
这些是我正在使用的文件。我不确定此错误会导致什么,我四处张望,找不到另一个示例。我认为平面名称空间错误表示在Flock类内部未找到Chicken类的构造函数。
我也刚刚尝试卸载并重新安装R,RStudio和Rcpp。
您正在Chicken
中声明一个Chicken.h
类,这在Family.cpp
中是已知的。您将在Chicken
中声明和定义Chicken.cpp
类。这两个类彼此独立。一种可能的解决方案是将Chicken.h
中的声明也包含在Chicken.cpp
中,并且仅定义方法而不是完整类:
// Chicken.cpp
#include <Rcpp.h>
#include "Chicken.h"
using namespace Rcpp;
Chicken::Chicken(int n){
id = n;
}
RCPP_EXPOSED_CLASS(Chicken)
RCPP_MODULE(chicken_cpp) {
class_<Chicken>("Chicken")
.constructor<int>()
;
}
或者,您可以将完整的定义从Chicken.cpp
移至Chicken.h
。两种方法都可以生成一个可以安装的软件包,但是我没有进一步测试。