python中带有静态成员的模板上的swig未定义符号
需要使用 swig 将带有一些静态成员的模板类的一部分导出到 python。 一切都编译良好,并且模块已正确创建,名称为 _pipeit.so;当我从 python 执行 import pipeline
时出现问题,因为它给出以下错误:
ImportError: ./_pipeit.so: undefined symbol: _ZN8gestface13FactoriesPoolINS_9GeneratorEED1Ev
问题是否是由于模板中静态成员的使用而引起的?如果是的话应该如何处理?
下面是 swig 接口文件的代码:
%module pipeit
%include "std_string.i"
%{
#define SWIG_FILE_WITH_INIT
#include "factory/factories.h"
%}
namespace gestface{
%newobject FactoriesPool::build;
template<typename BuildedT>
class FactoriesPool{
private:
FactoriesPool(){}
FactoriesPool(const FactoriesPool& b);
FactoriesPool& operator=(const FactoriesPool& b);
std::map< std::string, Factory<BuildedT>* > factory_map;
static FactoriesPool<BuildedT>* singleton_instance;
public:
~FactoriesPool();
static const ConfigurationTemplate& get_configuration_template(const std::string& class_name) throw(bad_class);
static BuildedT* build( const std::string& class_name,
const Configuration& conf = Configuration() ) throw(bad_parameter, bad_class);
};
%template( GeneratorFactoriesPool ) FactoriesPool< Generator >;
}
工厂、配置和生成器类也包含在接口文件中,为了简短起见,我不在这里报告它们,并且我不报告所有其他所需的 #includes 和异常处理同样的原因。
这是factories.h中的类的代码:
namespace gestface{
template<typename BuildedT>
class FactoriesPool{
private:
FactoriesPool(){}
FactoriesPool(const FactoriesPool& b);
FactoriesPool& operator=(const FactoriesPool& b);
std::map< std::string, Factory<BuildedT>* > factory_map;
static FactoriesPool<BuildedT>* singleton_instance;
public:
typedef BuildedT builded_t;
~FactoriesPool();
void add_factory(const std::string& class_name, Factory<BuildedT>* factory){
Factory<BuildedT>* f = factory_map[class_name];
if(f) delete f;
factory_map[class_name] = factory;
}
static FactoriesPool<BuildedT>* get_instance(){
if(!singleton_instance) singleton_instance = new FactoriesPool<BuildedT>();
return singleton_instance;
}
static const ConfigurationTemplate& get_configuration_template(const std::string& class_name) throw(bad_class){
if(!singleton_instance) singleton_instance = new FactoriesPool<BuildedT>();
const Factory<BuildedT>* f = singleton_instance->factory_map[class_name];
if(!f){
std::stringstream ss;
ss << "No such class: " << class_name;
throw bad_class(ss.str());
}
const ConfigurableFactory<BuildedT>* cf = dynamic_cast< const ConfigurableFactory<BuildedT>* >(f);
if(!cf){
std::stringstream ss;
ss << "Not configurable: " << class_name;
throw bad_class(ss.str());
}
return cf->get_configuration_template();
}
static BuildedT* build( const std::string& class_name,
const Configuration& conf = Configuration() ) throw(bad_parameter, bad_class){
if(!singleton_instance) singleton_instance = new FactoriesPool<BuildedT>();
const Factory<BuildedT>* f = singleton_instance->factory_map[class_name];
if(!f){
std::stringstream ss;
ss << "No such class: " << class_name;
throw bad_class(ss.str());
}
BuildedT* g;
if(conf.get_template().parameters_num() != 0){
const ConfigurableFactory<BuildedT>* cf = dynamic_cast< const ConfigurableFactory<BuildedT>* >(f);
if(!cf){
std::stringstream ss;
ss << "Not configurable: " << class_name;
throw bad_class(ss.str());
}
g = cf->build(conf);
}else {
g = f->build();
}
return g;
}
};
template<typename BuildedT>
FactoriesPool<BuildedT>* FactoriesPool<BuildedT>::singleton_instance = 0;
}
有人可以帮助我吗?
谢谢 卢卡
编辑: 这里遵循构建说明:
swig -Wall -c++ -python -o pipeit_wrap.cpp -outdir dist/Debug pipeit.i
g++ -c -g -ansi -I../../include -I/usr/include/python2.6 -fPIC -MMD -MP -MF build/Debug/pipeit_wrap.o.d pipeit_wrap.cpp -o build/Debug/pipeit_wrap.o
g++ -g -ansi -o dist/Debug/_pipeit.so build/Debug/pipeit_wrap.o -L../../dist/Debug/GNU-Linux-x86 -shared -lboost_system -lpipeit
哦,我错过了说我的模板化 FactoriesPool 类(以及所有其他类)包含在我的共享库 libpipeit 中。
无论如何,我认为这不是构建命令的问题,因为我的接口文件包含许多其他类,其中一些也是模板化的,并且在我尝试导出模板化的最后一个类并且还包含一些静态类之前,所有这些都工作正常成员。
The need is to export to python with swig a portion of a templated class with some static members.
All compiles well and the module is correctly created with the name _pipeit.so; the problem comes when from python i execute import pipeit
as it gives the following error:
ImportError: ./_pipeit.so: undefined symbol: _ZN8gestface13FactoriesPoolINS_9GeneratorEED1Ev
Does the problem is given from the usage of static members in a template? If so how they should be handled?
here follows the code of the swig interface file:
%module pipeit
%include "std_string.i"
%{
#define SWIG_FILE_WITH_INIT
#include "factory/factories.h"
%}
namespace gestface{
%newobject FactoriesPool::build;
template<typename BuildedT>
class FactoriesPool{
private:
FactoriesPool(){}
FactoriesPool(const FactoriesPool& b);
FactoriesPool& operator=(const FactoriesPool& b);
std::map< std::string, Factory<BuildedT>* > factory_map;
static FactoriesPool<BuildedT>* singleton_instance;
public:
~FactoriesPool();
static const ConfigurationTemplate& get_configuration_template(const std::string& class_name) throw(bad_class);
static BuildedT* build( const std::string& class_name,
const Configuration& conf = Configuration() ) throw(bad_parameter, bad_class);
};
%template( GeneratorFactoriesPool ) FactoriesPool< Generator >;
}
Factory, Configuration and Generator classes are included as well in the interface file, i don't report them here for shortness and i don't report all other needed #includes and exception handling for the same reason.
and here is the code of the class in the factories.h:
namespace gestface{
template<typename BuildedT>
class FactoriesPool{
private:
FactoriesPool(){}
FactoriesPool(const FactoriesPool& b);
FactoriesPool& operator=(const FactoriesPool& b);
std::map< std::string, Factory<BuildedT>* > factory_map;
static FactoriesPool<BuildedT>* singleton_instance;
public:
typedef BuildedT builded_t;
~FactoriesPool();
void add_factory(const std::string& class_name, Factory<BuildedT>* factory){
Factory<BuildedT>* f = factory_map[class_name];
if(f) delete f;
factory_map[class_name] = factory;
}
static FactoriesPool<BuildedT>* get_instance(){
if(!singleton_instance) singleton_instance = new FactoriesPool<BuildedT>();
return singleton_instance;
}
static const ConfigurationTemplate& get_configuration_template(const std::string& class_name) throw(bad_class){
if(!singleton_instance) singleton_instance = new FactoriesPool<BuildedT>();
const Factory<BuildedT>* f = singleton_instance->factory_map[class_name];
if(!f){
std::stringstream ss;
ss << "No such class: " << class_name;
throw bad_class(ss.str());
}
const ConfigurableFactory<BuildedT>* cf = dynamic_cast< const ConfigurableFactory<BuildedT>* >(f);
if(!cf){
std::stringstream ss;
ss << "Not configurable: " << class_name;
throw bad_class(ss.str());
}
return cf->get_configuration_template();
}
static BuildedT* build( const std::string& class_name,
const Configuration& conf = Configuration() ) throw(bad_parameter, bad_class){
if(!singleton_instance) singleton_instance = new FactoriesPool<BuildedT>();
const Factory<BuildedT>* f = singleton_instance->factory_map[class_name];
if(!f){
std::stringstream ss;
ss << "No such class: " << class_name;
throw bad_class(ss.str());
}
BuildedT* g;
if(conf.get_template().parameters_num() != 0){
const ConfigurableFactory<BuildedT>* cf = dynamic_cast< const ConfigurableFactory<BuildedT>* >(f);
if(!cf){
std::stringstream ss;
ss << "Not configurable: " << class_name;
throw bad_class(ss.str());
}
g = cf->build(conf);
}else {
g = f->build();
}
return g;
}
};
template<typename BuildedT>
FactoriesPool<BuildedT>* FactoriesPool<BuildedT>::singleton_instance = 0;
}
Does anyone can help me?
Thank you
Luca
EDIT:
Here follow building instructions:
swig -Wall -c++ -python -o pipeit_wrap.cpp -outdir dist/Debug pipeit.i
g++ -c -g -ansi -I../../include -I/usr/include/python2.6 -fPIC -MMD -MP -MF build/Debug/pipeit_wrap.o.d pipeit_wrap.cpp -o build/Debug/pipeit_wrap.o
g++ -g -ansi -o dist/Debug/_pipeit.so build/Debug/pipeit_wrap.o -L../../dist/Debug/GNU-Linux-x86 -shared -lboost_system -lpipeit
Oh, and i missed to say that my templated FactoriesPool class (as all others) is contained in my shared library libpipeit.
Anyway i think it is not a problem of building commands, because my the interface file contains a number of other classes, some of them templated as well and all worked fine before i tried to export this last class that is templated and also contains some static members.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
析构函数 ~FactoriesPool() 在哪里定义?运行时链接器正在寻找它。
Where is the destructor ~FactoriesPool() defined? The runtime linker is looking for it.