我有一个将类注册到集合中的工厂。工厂在一个dll中,类的注册可以在另一个dll中。当一个类从同一个dll中调用REGISTER_CLASS时,注册工作正常,但是当外部类调用它时,注册则无法正常工作。
违规行:#define REGISTER_CLASS(T)静态ClassMaker maker(#T);
I have tried to wrap the #define REGISTER_CLASS with extern "C"{ }
I have tried to declare it to export with the OPTUMDATA_API
#ifdef OPTUMDATA_EXPORTS
#define OPTUMDATA_API __declspec(dllexport)
#else
#define OPTUMDATA_API __declspec(dllimport)
#endif
OFactory,ClassMaker位于各自的dll中。
外部类位于其自己的dll中。
示例OFactory.h
#include "dlldef.h"
#include "OCollectable.h"
#include "IClassMaker.h"
#include <string>
#include <map>
class OPTUMDATA_API BaseFactory {
public:
static BaseFactory& Instance(); // Factory is a singleton
// Adds new class maker with a given key ( class name )
void RegisterMaker (const std::string&key, IClassMaker * maker);
// Creates new IClass from unknown class name
OCollectable* Create (std::string node) const;
OCollectable* Create(std::string node, OCollectable& oCol) const;
private:
BaseFactory() {}
BaseFactory(const BaseFactory& other);
BaseFactory& operator=(const BaseFactory& other);
std::map<std::string, IClassMaker*> _makers;
};
示例OFactory.cpp
#include "OFactory.h"
#include <string>
#include <vector>
#include "IClassMaker.h"
#include "OCollectable.h"
#include <Windows.h>
BaseFactory& BaseFactory::Instance()
{
static BaseFactory factory;
return factory;
}
void BaseFactory::RegisterMaker(const std::string& key, IClassMaker* maker)
{
// Validate uniquness and add to the map
if (_makers.find(key) != _makers.end())
{
throw new std::exception("Multiple makers for given key!");
}
_makers[key] = maker;
}
OCollectable* BaseFactory::Create(std::string node) const
{
std::vector<std::string> strs;
boost::split(strs,node,boost::is_any_of(" "));
// Look up the maker by nodes name
std::string key(strs[0]);
auto i = _makers.find(key);
if (i == _makers.end())
{
throw new std::exception("Oject has not been registered!");
}
IClassMaker* maker = i->second;
// Invoke create polymorphiclly
return maker->Create(node);
}
OCollectable* BaseFactory::Create(std::string node, OCollectable& oCol)
const
{
std::vector<std::string> strs;
boost::split(strs,node,boost::is_any_of(" "));
// Look up the maker by nodes name
std::string key(strs[0]);
auto i = _makers.find(key);
if (i == _makers.end())
{
throw new std::exception("Oject has not been registered!");
}
IClassMaker* maker = i->second;
// Invoke create polymorphiclly
return maker->Create(node,oCol);
}
例如:ClassMaker.h
#include "IClassMaker.h"
#include "OCollectable.h"
#include "OFactory.h"
#define REGISTER_CLASS(T) static ClassMaker<T> maker(#T);
template<typename T>
class OPTUMDATA_API ClassMaker : public IClassMaker
{
public:
/// When created, the class maker will automaticly register itself with
the factory
/// Note - you are discouraged from using ClassMaker outside
REGISTER_CLASS macro
/// For example, creating ClassMaker on the stack will end up badly
ClassMaker(const std::string& key)
{
BaseFactory::Instance().RegisterMaker(key, this);
}
virtual OCollectable* Create(std::string node) const
{
std::vector<std::string> strs;
boost::split(strs,node,boost::is_any_of(" "));
//// Create new instance of T using constructor from string
//// Assumes T has a constructor that accepts std::string
//std::string str = fields[1];
return new T(strs[1].c_str());
}
virtual OCollectable* Create(std::string node, OCollectable& oCol) const
{
std::vector<std::string> strs;
boost::split(strs,node,boost::is_any_of(" "));
//// Create new instance of T using constructor from string
//// Assumes T has a constructor that accepts std::string
//std::string str = fields[1];
return new T(strs[1].c_str(), oCol);
}
};
外部类示例.cpp文件
#include "term_store.h"
#include "ClassMaker.h"
#include "OFactory.h"
REGISTER_CLASS(TermStringClass);
using namespace std;
// Term String Class member functions
// Constructors
TermStringClass::TermStringClass(const TermStringClass &ts): term(ts.term)
{}
TermStringClass::TermStringClass(const OString &t): term(t){}
TermStringClass::TermStringClass(const OString &t, OCollectable& s):
term(t){}
TermStringClass::TermStringClass(const char *t): term(t) {}
TermStringClass::TermStringClass() {
}
TermStringClass::~TermStringClass() {
}
外部类示例.h文件
#include <ClassMaker.h>
#include <OFactory.h>
//using namespace std;
class TermStringClass: public OCollectable {
public:
// Constructors
TermStringClass(const TermStringClass &ts);
TermStringClass(const OString &t);
TermStringClass(const OString &t, OCollectable& s);
TermStringClass(const char *t);
TermStringClass();
virtual ~TermStringClass();
};
在外部类.obj文件中接收链接器错误
错误64错误LNK2019:未解决的外部符号“ __declspec(dllimport)公共:__thiscall ClassMaker :: ClassMaker(class std :: basic_string,class std :: allocator> const&)”(__imp _ ?? 0?$ ClassMaker @ VTermStringClass @@@ QAE @ ABV?$ basic_string @ DU?$ char_traits @ D @ std @@ V?$ allocator @ D @ 2 @@ std @@@@ Z)在函数“ void __cdecl'maker的动态初始化程序”中引用'(void)“(?? __ Emaker @@ YAXXZ)