2

我知道如何对不包含类的 dll 使用显式链接,但如何链接包含类的 dll,例如:

class math{
public:
int sum(int,int);
};

加载它:

    typedef int(*func)(int,int);
    int main{
    HINSTANCE hDLL;               // Handle to DLL
    hDLL = LoadLibrary("math.dll");
        func add=(func)GetProcAddress(hDLL, "sum");
    add(4,5);
 return 0;
    }

如果我这样做,它会停止工作并退出程序,如果我删除它可以工作的类

4

2 回答 2

2

C++ 编译器使用名称修饰来唯一区分程序中的标识符。这种修改会导致名称与您在程序中使用的普通标识符有很大不同。因此,使用GetProcAddressC++ 编写的驻留在 DLL 中的代码通常是不切实际的。相反,我建议使用__declspec(dllexport)and__declspec(dllimport)提供对驻留在 DLL 中的代码的轻松访问。

在您的 DLL 项目中,您需要添加一个预处理器定义,其名称如“EXPORT_CLASSES”或 DLL 唯一的名称。这将被您的 DLL 和程序用来确定特定声明是应该由 DLL 导出还是由程序导入。

dllstuff.h

#ifdef EXPORT_CLASSES
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif

然后,您将更改类声明math以使用它。当 DLL 被编译时,IMPORT_EXPORT 将等于__declspec(dllexport)并指示编译器和链接器该类的定义应该公开(即通过 DLL 的导出表)。

数学类.h

#include "dllstuff.h"

class IMPORT_EXPORT math
{
public:
    int sum(int, int);
};

现在,您在主应用程序中所要做的就是在mathclass.h您想要使用数学课程的任何时间包含在内。您现在可以实例化一个实例math并访问它的成员函数。

#include "mathclass.h"
int main()
{
    math m;
    int result = m.sum(1, 2);
}

这当然只是对该过程的基本描述。网上有很多文章(包括 SO),提供了更详细的信息。

于 2013-07-02T20:14:08.560 回答
2

GetProcAddress 可以从 DLL 加载导出的符号,前提是您使用正确的名称调用它。

在您的情况下,该功能首先没有导出。如果是这样,它肯定不会被称为“总和”,而是一些 20-40 个字符的乱码。

对于将 DLL 与 C++ 代码一起使用,您需要完全放弃 GetProcAddress 方式,而只依赖于映射名称的 implib。

为此,您将 __declspec(dllexport) 添加到类(最好在客户端使用 dllimport),并将您的 DLL 项目添加为项目参考。或者,将与 DLL 一起创建的 .lib 添加到客户端项目。

于 2013-07-02T20:02:27.043 回答