swig c++ 到 perl:无法执行继承的 public 基础方法 class
swig c++ to perl: not able to execute inherited public method Of base class
我正在尝试为某些 C++ classes(可能使用模板)生成 Perl 包,并面临派生 class 对象无法调用基 class 方法,它在 C++ 中公开继承 class。
阅读 swig 4.0 手册后,我能够设置我的 classes(包括模板)并正确编译它们而没有错误。我开始知道如何订购它们以及如何分离模块以便正确编译它们。
派生的 class 对象在 perl 中使用时,无法访问基础 class 方法 - 这正是我需要帮助的地方。如果我查看对象转储(使用 objdump -t
命令),我会看到 base_hello() 方法仍未定义但似乎无法弄清楚为什么?
我尝试 link 明确地使用 DerivedClass.so 文件但无济于事。
请注意,我能够使同样的东西工作,但没有模板。我能够在我的 Perl 脚本中从派生的 class 对象执行基本 class 方法。
任何人都可以指出我可以进一步调查的方向吗?目前我无法在 Internet 上为我的用例找到任何相关信息,即 无法在 Perl.
中执行基本 class 方法
如果您对这个问题感兴趣,请找到下面用来做这个小测试的文件:
Perl 程序抛出未定义符号错误:
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__
更新: 添加编译命令
#### 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
您需要强制实例化模板 class BaseClass<int>
以便在 BaseClass.so
中定义符号 BaseClass<int>::base_hello(int)
。因此,将以下行添加到 BaseClass.cpp
的底部:
template class BaseClass<int>; // <-- explicitly instantiate the template specialization for int
然后重新编译一切,它应该可以工作。另见 this post
我正在尝试为某些 C++ classes(可能使用模板)生成 Perl 包,并面临派生 class 对象无法调用基 class 方法,它在 C++ 中公开继承 class。
阅读 swig 4.0 手册后,我能够设置我的 classes(包括模板)并正确编译它们而没有错误。我开始知道如何订购它们以及如何分离模块以便正确编译它们。
派生的 class 对象在 perl 中使用时,无法访问基础 class 方法 - 这正是我需要帮助的地方。如果我查看对象转储(使用 objdump -t
命令),我会看到 base_hello() 方法仍未定义但似乎无法弄清楚为什么?
我尝试 link 明确地使用 DerivedClass.so 文件但无济于事。
请注意,我能够使同样的东西工作,但没有模板。我能够在我的 Perl 脚本中从派生的 class 对象执行基本 class 方法。
任何人都可以指出我可以进一步调查的方向吗?目前我无法在 Internet 上为我的用例找到任何相关信息,即 无法在 Perl.
中执行基本 class 方法如果您对这个问题感兴趣,请找到下面用来做这个小测试的文件:
Perl 程序抛出未定义符号错误:
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__
更新: 添加编译命令
#### 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
您需要强制实例化模板 class BaseClass<int>
以便在 BaseClass.so
中定义符号 BaseClass<int>::base_hello(int)
。因此,将以下行添加到 BaseClass.cpp
的底部:
template class BaseClass<int>; // <-- explicitly instantiate the template specialization for int
然后重新编译一切,它应该可以工作。另见 this post