【问题标题】:swig undefined symbol on templates with static members in python在python中带有静态成员的模板上痛饮未定义的符号
【发布时间】:2011-03-19 12:35:59
【问题描述】:

需要将带有一些静态成员的模板类的一部分导出到 python。 一切编译良好,模块正确创建,名称为 _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 类也包含在接口文件中,为了简短起见,我不在这里报告它们,并且出于同样的原因,我不报告所有其他需要的#includes 和异常处理。

这是 factory.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

哦,我忘了说我的模板化工厂池类(与所有其他类一样)包含在我的共享库 libpipeit 中。

无论如何我认为这不是构建命令的问题,因为我的接口文件包含许多其他类,其中一些也是模板化的,并且在我尝试导出最后一个模板化的类之前一切正常包含一些静态成员。

标签: c++ python templates swig static-members


【解决方案1】:

析构函数 ~FactoriesPool() 在哪里定义?运行时链接器正在寻找它。

【讨论】:

  • 你是否使用了“c++filt”对错误信息中的字符串进行了解码?
  • 我不知道。我认为从现在开始它将非常有用。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多