2011-03-19 72 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