我正在开发一个有一些"模块"的项目.我在这里称之为模块的是一个简单的类,它实现了一个特定的功能,并从一个强制接口的抽象类GenericModule派生.
应该在将来添加新模块.
可以同时加载模块的多个实例,也可以不加载,具体取决于配置文件.
我认为,如果未来的开发人员能够在一个简单的行中"注册"他的模块系统就会很棒.或多或少与他们在谷歌测试中注册测试的方式相同.
我正在使用visual studio 2005构建项目.代码完全在库中,除了exec项目中的main().我想保持这种方式.
我在谷歌测试中找到了灵感.
我创建了一个模板化的工厂.看起来或多或少像这样(我跳过了不感兴趣的部分,以保持这个问题有点可读):
class CModuleFactory : boost::noncopyable
{
public:
virtual ~CModuleFactory() {};
virtual CModuleGenerique* operator()(
const boost::property_tree::ptree& rParametres ) const = 0;
};
template <class T>
class CModuleFactoryImpl : public CModuleFactory
{
public:
CModuleGenerique* operator()(
const boost::property_tree::ptree& rParametres ) const
{
return new T( rParametres );
}
};
Run Code Online (Sandbox Code Playgroud)
和一个应该注册模块并将其工厂添加到列表的方法.
class CGenericModule
{
// ...
template <class T>
static int declareModule( const std::string& rstrModuleName )
{
// creation de la factory
CModuleFactoryImpl<T>* pFactory = new CModuleFactoryImpl<T>();
// adds the factory to a map of "id" => factory
CAcquisition::s_mapModuleFactory()[rstrModuleName ] = pFactory;
return 0;
}
};
Run Code Online (Sandbox Code Playgroud)
现在在模块中,我需要做的就是声明一个模块:
static int initModule =
acquisition::CGenericModule::declareModule<acquisition::modules::CMyMod>(
"mod_name"
);
Run Code Online (Sandbox Code Playgroud)
(将来它将被包装在允许的宏中
DECLARE_MODULE( "mod_name", acquisition::modules::CMyMod );
Run Code Online (Sandbox Code Playgroud)
)
好吧,现在问题.
问题是,它确实有效,但不完全是我想要的方式.
如果我将initModule的定义放在模块的.cpp(我希望拥有它)中(甚至在.h中),则不会调用declareModule方法.如果我将静态init放在一个用过的.cpp文件中..它可以工作.
使用我的意思是:在其他地方调用代码.
视觉工作室似乎在构建库时丢弃了整个obj.我猜那是因为它没有在任何地方使用.
我激活了详细的链接,并在传递n°2中列出了库中的.objs,并且模块的.obj不存在.
我找到了这个并尝试添加/OPT:NOREF
选项,但它没有用.我没有尝试在函数的.h中放置一个函数并从其他地方调用它,因为整个点就是能够在它的文件中的一行中声明它.
另外我认为问题与此类似,但解决方案是针对g ++而不是视觉:'(
编辑:我刚刚阅读了这个问题的答案中的注释.好吧,如果我#include来自另一个.cpp的模块的.h,并将init放在模块的.h中.它工作,初始化实际上完成两次...每个编译单元一次?好吧它似乎发生在模块的编译单元......
如果你不同意我正在尝试做的事情,请随意告诉我,但我仍然对解决方案感兴趣
我根据 wxWidgets 的代码得到了类似的东西,但是我只将它用作 DLL。然而,wxWidgets 代码可以与静态库一起使用。
可能有所不同的一点是,在 wx 中,以下内容的等价物是在类范围内定义的。
static int initModule =
acquisition::CGenericModule::declareModule<acquisition::modules::CMyMod>(
"mod_name"
);
Run Code Online (Sandbox Code Playgroud)
类似于下面的内容,Factory
因为它是静态的,所以它的创建会导致它被加载到工厂列表中。
#define DECLARE_CLASS(name)\
class name: public Interface { \
private: \
static Factory m_reg;\
static std::auto_ptr<Interface > clone();
#define IMPLEMENT_IAUTH(name,method)\
Factory name::m_reg(method,name::clone);\
Run Code Online (Sandbox Code Playgroud)