Search code examples
rcpp

Unable to load shared object with inherited class in a R package


I am creating a R package using Rcpp. In this package, I want to create classes that will not be exported to R, with a class inheriting from another.

I created a package with Rcpp.package.skeleton(), to which I added two files in the src directory.

I have a file A.h:

class A {
 public:
  virtual ~A();
};

class B : public A {
public:
  B();
};

And a file A.cpp:

#include "A.h"

B::B() { }

When compiling the package, I get the following error:

Error in dyn.load(dllfile) : 
  unable to load shared object '.../test/src/test.so':
  .../test/src/test.so: undefined symbol: _ZTI1A

I only find resources about exposing such classes to R, but I am wondering whether it would be possible to use such a class internally, without exposing it to R?


Edit: If I understand correctly, the files necessary for building the package are:

NAMESPACE:

useDynLib(test, .registration=TRUE)
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)

DESCRIPTION:

Package: test
Type: Package
Title: What the Package Does in One 'Title Case' Line
Version: 1.0
Date: 2020-06-23
Author: Your Name
Maintainer: Your Name <your@email.com>
Description: One paragraph description of what the package does as one
        or more full sentences.
License: GPL (>= 2)
Imports: Rcpp (>= 1.0.4)
LinkingTo: Rcpp
RoxygenNote: 7.1.0

Solution

  • This has nothing to do with Rcpp. Your class A is simply "too virtual". If I combine your files A.h and A.cpp with a simple main.cpp of this form

    #include <cstdio>
    
    int main(int argc, char *argv[]) {
      std::printf("Hello, world.");
    }
    

    and try to compile it I also get an error:

    edd@rob:/tmp$ g++ -o A A.cpp main.cpp 
    /usr/bin/ld: /tmp/ccbuZv0r.o: in function `A::A()':
    A.cpp:(.text._ZN1AC2Ev[_ZN1AC5Ev]+0xf): undefined reference to `vtable for A'
    /usr/bin/ld: /tmp/ccbuZv0r.o: in function `B::~B()':
    A.cpp:(.text._ZN1BD2Ev[_ZN1BD5Ev]+0x26): undefined reference to `A::~A()'
    /usr/bin/ld: /tmp/ccbuZv0r.o:(.data.rel.ro._ZTI1B[_ZTI1B]+0x10): undefined reference to `typeinfo for A'
    collect2: error: ld returned 1 exit status
    edd@rob:/tmp$ 
    

    Which is pretty much what you got from R as well

    edd@rob:/tmp$ c++filt _ZTI1A
    typeinfo for A
    edd@rob:/tmp$ 
    

    So your package was simply insufficient -- nothing to do with Rcpp.