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