swig неопределенный символ в шаблонах со статическими элементами в python
Нужно экспортировать в python с помощью swig часть шаблонного класса с некоторыми статическими членами. Все хорошо компилируется и модуль правильно создан с именем _pipeit.so; проблема возникает, когда из Python я выполняю import pipeit
как это дает следующую ошибку:
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 >;
}
Классы Factory, Configuration и Generator также включены в интерфейсный файл, я не сообщаю о них здесь для краткости и не сообщаю обо всех других необходимых #include и обработке исключений по той же причине.
и вот код класса на фабриках.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.
Во всяком случае, я думаю, что это не проблема построения команд, потому что мой интерфейсный файл содержит ряд других классов, некоторые из них также шаблонизированы и все работали нормально, прежде чем я попытался экспортировать этот последний класс, который является шаблонным, а также содержит некоторые статические члены.
1 ответ
Где деструктор ~FactoriesPool() определен? Линкера времени выполнения ищет его.