导出:使用c ++进行DLL链接

时间:2013-07-02 19:57:35

标签: c++

我知道如何为不包含类的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;
    }

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

2 个答案:

答案 0 :(得分:2)

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

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

对于使用带有C ++代码的DLL,您需要完全删除GetProcAddress方法,并且只依赖于映射名称的implib。

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

答案 1 :(得分:2)

C ++编译器使用name mangling来唯一地区分程序中的标识符。此修改导致名称与您在程序中使用的普通标识符明显不同。因此使用GetProcAddress对于访问驻留在DLL中的C ++编写的代码通常是不切实际的。相反,我建议使用__declspec(dllexport)__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的导出表)。

  

mathclass.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),提供更详细的信息。