我创建了一个DLL项目并成功构建了它。然后我尝试在另一个Project,TEST中使用DLL,我收到以下错误。
Error 1 error LNK2001: unresolved external symbol "public: void __thiscall SnoMessage::setRawMessageName(class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >)" (?setRawMessageName@SnoMessage@@QAEXV?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@@Z)
我在链接器属性中添加了所需的lib,并且还在TEST include目录中添加了头文件。因此该功能正在被识别,但它不断给出这些错误。 DLL由以下文件组成
SnoMessage.h
#pragma once
#include "StdAfx.h"
class SnoMessage
{
public:
__declspec(dllexport) SnoMessage(void);
__declspec(dllexport) ~SnoMessage(void);
__declspec(dllexport) void setRawMessageName(CString messageName);
__declspec(dllexport) void setRawMessageType(CString messageType);
__declspec(dllexport) void setRawMessageAttributes(std::map<CString,CString> attributes);
__declspec(dllexport) CString getRawMessageName();
__declspec(dllexport) CString getRawMessageType();
__declspec(dllexport) std::map<CString,CString> getRawMessageAttributes();
private:
CString messageName;
CString messageType;
std::map<CString,CString> attributes;
};
SnoMessage.cpp
#include "stdafx.h"
#include "SnoMessage.h"
SnoMessage::SnoMessage(void)
{
}
SnoMessage::~SnoMessage(void)
{
}
void SnoMessage::setRawMessageName(CString messageName){
this->messageName = messageName;
}
void SnoMessage::setRawMessageType(CString messageType){
this->messageType = messageType;
}
void SnoMessage::setRawMessageAttributes(std::map<CString,CString> attributes){
this->attributes = attributes;
}
CString SnoMessage::getRawMessageName(){
return messageName;
}
CString SnoMessage::getRawMessageType(){
return messageType;
}
std::map<CString,CString> SnoMessage::getRawMessageAttributes(){
return attributes;
}
在测试中我正在做以下事情:
TEST.CPP
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "SnoMessage.h"
int _tmain(int argc, _TCHAR* argv[])
{
SnoMessage *msg = new SnoMessage();
msg->setRawMessageName("TEST");
return 0;
}
如果您需要更多信息,请告诉我们,谢谢。
答案 0 :(得分:12)
在你的dll中,在你想要用于导出defs的某个标题中定义它...
MyExports.h
#ifdef SNOMESSAGE_EXPORTS
#define SNOMESSAGE_API __declspec(dllexport)
#else
#define SNOMESSAGE_API __declspec(dllimport)
#endif
现在在你的dll中你只需定义SNOMESSAGE_EXPORTS,然后当你的dll被编译时,你的类和方法将对exe可见。但是当你在exe中包含那些相同的标题时,宏将导入它们而不是导出。
//In the DLL this is == to export, in the executable this is import. Problem solved.
class SNOMESSAGE_API SnoMessage
{
public:
//...
};
您不再需要导出每个成员,只需要导出类。
答案 1 :(得分:0)
我会将整个类标记为已导出,而不仅仅是其成员函数。另外,根据this conversation的建议,您需要根据您是在DLL中包含标头还是使用DLL的代码来指定__declspec(dllecport)
或__declspec(dllimport)
;并在DLL项目中定义保护宏。
答案 2 :(得分:0)
编译DLL时,你应该有__declspec(dllexport),但是当你编译exe时你应该有__declspec(dllimport)。最简单的方法是在“DLL”和“out of DLL”中使用#define,使其具有不同的值。也可以导出整个类而不是单个方法。
答案 3 :(得分:0)
有一种情况,dll编译使用C调用而exe使用标准调用,x64下的链接没有问题,但是使用win32时会显示这个链接错误2001。对于这种情况,dll和exe都使用C调用适用于 win32 平台 (https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/name-decoration?view=msvc-160)。