pauloss
pauloss

Reputation: 47

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 <[email protected]>
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

Upvotes: 1

Views: 94

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368201

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.

Upvotes: 2

Related Questions