I am trying to generate Perl packages for some C++ classes (which may use templates), and facing this weird issue that the derived class object is unable to call the base class method, which it inherited in C++ class publicly.
After reading the swig 4.0 manual, I was able to setup my classes (including template ones) and compile them properly sans errors. I got to know how to order them and how to separate the modules in order to get them compiled properly.
Somehow the derived class object, when used in perl, is unable to access base class method - and here is where I need some help. If I look at the object dump (using objdump -t
command), I see that the base_hello() method is still undefined but can't seem to figure out why?
I tried to link it explicitly with the DerivedClass.so file but to no avail.
Note that I was able to make the same thing work but sans the templates. I was able to execute the base class method from the derived class object, in my Perl script.
Can anyone point me in a direction where I could investigate further? Currently I am not able to find any related information on internet for my use case i.e. unable to execute base class method in Perl.
If this problem interests you, please find the files used below to do this small test:
Perl Program throws undefined symbol error:
20190901 03:25 [compuser@lenovoe470:template-base-class]$ perl testDerivedClass.pl
Hello from derived class
perl: symbol lookup error: /home/compuser/mystuff/study/ace/swig-with-ace/template-base-class/BaseClass.so: undefined symbol: _ZN9BaseClassIiE10base_helloEi
20190901 03:25 [compuser@lenovoe470:template-base-class]$
Baseclass.i
%module BaseClass
%{
#include "BaseClass.h"
%}
%include "BaseClass.h"
%template(intBaseClass) BaseClass< int > ;
Derivedclass.i
%module DerivedClass
%import "BaseClass.i"
%{
#include "DerivedClass.h"
%}
%include "DerivedClass.h"
Baseclass.h
#ifndef BC__
#define BC__
#include <iostream>
template <class T>
class BaseClass {
public:
void base_hello(T value);
};
#endif /* BC__ */
Baseclass.cpp
#include "BaseClass.h"
template <class T>
void BaseClass<T>::base_hello(T value) {
std::cerr << "Hello from base class: " << value << "\n";
}
Derivedclass.h
#ifndef __DC_
#define __DC_
#include "BaseClass.h"
class DerivedClass : public BaseClass <int> {
public:
void derived_hello();
};
#endif /* __DC_ */
Derivedclass.cpp
#include "DerivedClass.h"
void DerivedClass::derived_hello() {
std::cerr << "Hello from derived class\n";
}
testDerivedClass.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use DerivedClass;
my $obj = new DerivedClass::DerivedClass();
$obj->derived_hello();
$obj->base_hello();
__END__
UPDATE: Adding compilation commands
#### For Base Class
/usr/local/bin/swig -c++ -perl5 BaseClass.i
g++ -std=c++11 -c -fPIC `perl -MConfig -e 'print join(" ", @Config{qw(ccflags optimize cccdlflags)}, "-I$Config{archlib}/CORE")'` -D_GNU_SOURCE -L. BaseClass.cpp BaseClass_wrap.cxx
g++ -std=c++11 -lstdc++ `perl -MConfig -e 'print $Config{lddlflags}'` -L. BaseClass.o BaseClass_wrap.o -o BaseClass.so
#### For Derived Class
/usr/local/bin/swig -c++ -perl5 DerivedClass.i
g++ -std=c++11 -c -fPIC `perl -MConfig -e 'print join(" ", @Config{qw(ccflags optimize cccdlflags)}, "-I$Config{archlib}/CORE")'` -D_GNU_SOURCE -L. DerivedClass.cpp DerivedClass_wrap.cxx
g++ -std=c++11 -lstdc++ `perl -MConfig -e 'print $Config{lddlflags}'` -L. DerivedClass.o DerivedClass_wrap.o -o DerivedClass.so