2011-03-19 109 views
0

需要用swig将一部分模板类与一些静态成员一起导出到python。 所有编译良好,模块正确创建名称_pipeit.so;问题来自蟒当我执行import pipeit,因为它提供了以下错误:在python中使用静态成员的模板中swig undefined symbol

ImportError: ./_pipeit.so: undefined symbol: _ZN8gestface13FactoriesPoolINS_9GeneratorEED1Ev 

问题是否是从静态成员在模板中使用给定的?如果是的话应该如何处理?

这里遵循痛饮接口文件的代码:

%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。

无论如何,我认为这不是一个建立命令的问题,因为我的界面文件包含一些其他的类,其中一些模板以及所有工作正常之前我试图导出这最后一个类是模板和还包含一些静态成员。

+0

我们需要查看您的构建步骤。看起来,当你调用g ++时,你无法将你的代码链接到SWIG生成的库。另请参阅[G ++链接和SWIG](http://stackoverflow.com/questions/5302933/g-linking-and-swig) – lefticus 2011-03-19 13:44:05

+0

我添加了建筑命令和一些更多评论,感谢你的有趣 – 2011-03-19 14:00:36

回答

1

哪里是析构函数〜FactoriesPool()定义?运行时链接程序正在寻找它。

+0

哦天啊...我我非常尴尬......真的很感谢你 – 2011-03-19 14:18:07

+1

你是否使用“C++ filt”来将错误信息中的字符串去掉? – 2011-03-19 14:19:32

+0

我不知道。我认为从现在起它将非常有用。再次感谢你。 – 2011-03-19 14:27:29