1

我有一个库(dll),它公开了一个类及其构造函数,这些构造函数应该在其他模块(exe 和 dll)中使用。我能够从其他库模块而不是 exe 模块实例化该类。我在链接期间收到链接器错误 - 'error LNK2019: unresolved external symbol'。我很困惑为什么在其他库项目而不是 exe 项目中使用时链接成功。有人可以帮我吗?

以下是类声明:

class __declspec(dllimport) MyException
{
public:
MyException(unsigned int _line, const char *_file, const char *_function, MyExceptionType _type, const wchar_t* _message = 0, ...);
};

这是整个错误:错误 LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl MyException::MyException(unsigned int,char const *,char const *,enum MyException::MyExceptionType,unsigned short const *,... )" (_ imp ??0MyException@@QAA@IPBD0W4MyExceptionType@0@PBGZZ) 在函数 "public: __thiscall MyClassUsesMyException::MyClassUsesMyException(class SomeClass *,int)" (??0MyClassUsesMyException@@QAE@PAVSomeClass@@H@ Z)

MyClassUsesMyException 正在“MyApp.cpp”中实例化。

谢谢,拉克什。

4

1 回答 1

0

更新:wchar_t并不总是原生的

经过相当长时间的信息交流并从 OP 获得更多信息后,问题很重要:

class __declspec(dllimport) MyException
{
public:
    MyException(unsigned int _line, 
        const char *_file, 
        const char *_function, 
        MyExceptionType _type, 
        const wchar_t* _message = 0, // <<== note wchar_t type
        ...);
};

Visual C++ 可以配置为将其wchar_t视为本机类型或不视为本机类型。当不被视为本机类型时,unsigned short是指定的宏替换wchar_t. 链接器抱怨上述函数无法解析,但真正引起我注意的是未定义符号的尾部:

,unsigned short const *,...)

注意unsigned short. 这向我暗示编译器wchar_t在编译 EXE 时使用的是非本机。我认为可能是 DLL 编译时wchar_t配置为本机,因此引入了不同的签名,因此在链接时不匹配。

如果你对这就是问题感到惊讶,想象一下我和 Rakesh 有多惊讶 =P


原始答案

该类应位于具有预处理器逻辑的单个公共标头中,以确定声明的正确导入/导出状态。像这样:

我的DLL.h

#ifndef MYDLL_H
#define MYDLL_H

// setup an import/export macro based on whether the 
//  DLL implementing this class is being compiled or
//  a client of the DLL is using it. Only the MyDLL.DLL
//  project should define MYDLL_EXPORTS. What it is 
//  defined as is not relevant. *That* it is defined *is*.

#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

class MYDLL_API MyException
{
    // your class definition here...
};

#endif

然后,在实现异常的 DLL 项目中(并且在该项目中),将 MYDLL_EXPORTS 添加到项目配置中的预处理器定义列表中。

于 2013-02-18T05:29:08.443 回答