C ++导出#define和另一个DLL中的引用

时间:2019-02-05 17:22:07

标签: visual-c++

我有一个将类注册到集合中的工厂。工厂在一个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)

0 个答案:

没有答案