c ++ factory:通过运行时加载的插件扩展寄存器

时间:2015-12-14 21:37:48

标签: c++ plugins factory

简而言之:我想加载一个扩展Factory地图的共享库,而不必重新编译基本程序。我搜索和搜索,但不了解如何更进一步:dlopen? (但我没有得到dlsym的东西)。别的什么? 如果我提供了我的程序所需的所有自定义库,我可以重新链接"一切都通过添加plugin.so?如果我的代码需要提升,并且用户没有boost-devel会发生什么?

详细信息:假设我的代码工厂正常运行代码,例如:

class Voxel_Factory {
public:
    static std::map<std::string, boost::shared_ptr<Voxel_Factory> >* Voxel_Factories;
protected:

    static std::map<std::string, boost::shared_ptr<Voxel_Factory> >* get_map(){
        if(!Voxel_Factories){
            Voxel_Factories = new std::map<std::string, boost::shared_ptr<Voxel_Factory> >;
        }
        return Voxel_Factories;
    }
public:
    virtual boost::shared_ptr<Voxel> create_voxel(foo bar) = 0 ;
};


template<class V>
class Spe_Voxel_Factory : public Voxel_Factory {
public:
    boost::shared_ptr<Voxel> create_voxel(foo bar){
        return boost::shared_ptr<Voxel>(new V(bar));
    }
};


template<class V>
class Spe_Voxel_Register : public Spe_Voxel_Factory<V> {
public:
    Spe_Voxel_Register(const std::string &s){
        Voxel_Factory::get_map()->insert(
                std::make_pair(s,
                               boost::shared_ptr<Voxel_Factory>(new Spe_Voxel_Factory<V>) ) );
    }
};

我注册我的课程:

Spe_Voxel_Register<Voxel_Cauchy> Voxel_Cauchy::reg("cauchy");
等等 我已经有了完整的代码。

现在我想拥有一个插件系统。例如,让我们说Voxel_Cauchy使用的所有文件实际上都是在其他地方开发的:有人使用主代码的包含,并生成一个库voxel_cauchy.so,并将其放入特定目录:plugins_folder。我是为测试目的而做的,我可以毫无问题地创建所说的voxel_cauchy.so文件。

问题:我应该在主代码中做些什么,以便查看plugins_folder并正确更新我的工厂地图,以便我可以致电:

(*Voxel_Factory::Voxel_Factories)[voxel_to_create]->create_voxel(bar)

其中voxel_to_create =&#34;柯西&#34; ?

欢迎提供任何提示或良好的参考链接。我在Linux上使用cmake,但跨平台解决方案会更好。

我尝试在google&#34; c ++中如何在插件中扩展工厂地图&#34;&#34; c ++在运行时对象工厂加载共享的lybrary&#34;,但我找不到虽然我通过网络上的例子来建立我的工厂,但是与我的情况类似。

1 个答案:

答案 0 :(得分:0)

在Windows中,您可以使用LoadLibrary加载共享库。 加载共享库的过程开始初始化o全局变量,这意味着C ++对象调用了结构。 在共享库中,您可以创建类Init:

class Init
{
public:
    Init()
    {
        Spe_Voxel_Register<Voxel_Cauchy> Voxel_Cauchy::reg("cauchy");
        Spe_Voxel_Register<Voxel_Cauchy2> Voxel_Cauchy::reg("cauchy2");
            ...
    }
};

Init init1;

提醒您的库和插件库必须使用相同的编译器进行编译,并使用相同的c / c ++运行时。