使用Rcpp打包并尝试让一个类引用另一个类

问题描述 投票:3回答:1

我正在尝试编写实现棋盘游戏的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。

c++ r rcpp
1个回答
0
投票

您正在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。两种方法都可以生成一个可以安装的软件包,但是我没有进一步测试。

© www.soinside.com 2019 - 2024. All rights reserved.