C++中的非托管DLL

Pet*_* C. 8 c++ dll unmanaged

我一直在阅读很多关于C++中非托管DLL的教程/文章.然而,对于我的生活,我似乎无法掌握这个概念.我很容易因为它是否需要头文件,如何导出它,是否需要.lib文件以及你有什么看似不一致而感到困惑.

所以,我们假设我只有这样的函数:

public int calculateSquare(int num)
{
    return num*num;
}
Run Code Online (Sandbox Code Playgroud)

忽略实际的代码,我需要做什么才能将这个简单的函数本身变成一个我可以调用的DLL?我只是添加__dllexport或其他任何内容到第一行还是我需要标题?所有这一切让我感到困惑.

QBz*_*ziZ 15

我不能强调这一点,C++编译器没有看到头文件,在预处理器完成后,只有一个大的源文件(也称为编译单元).因此严格来说,您不需要标头来从dll导出此函数.您需要的是某种形式的条件编译,以导出您正在编译的DLL中的函数并将其导入客户端代码中.

通常,这是通过宏和头文件的组合来完成的.您创建一个名为MYIMPORTEXPORT的宏,并通过使用宏条件语句使其在dll中与__declspec(dllexport)一样工作,在客户端代码中使用__declspec(dllimport).

在文件MYIMPORTEXPORT.h中

#ifdef SOME_CONDITION
#define MYIMPORTEXPORT __declspec( dllexport )
#else
#define MYIMPORTEXPORT __declspec( dllimport )
#endif
Run Code Online (Sandbox Code Playgroud)

在文件MyHeader.h中

#include <MyImportExport.h>

MYIMPORTEXPORT public int calculateSquare(int num)
{
    return num*num;
}
Run Code Online (Sandbox Code Playgroud)

在dll .cpp文件中

#define SOME_CONDITION

#include <MyHeader.h>
Run Code Online (Sandbox Code Playgroud)

在客户端代码.cpp文件中

#include <MyHeader.h>
Run Code Online (Sandbox Code Playgroud)

当然,您还需要向链接器发出信号,表明您正在使用/ DLL选项构建一个dll .

构建过程也将生成.lib文件,这是一个静态库 - 在这种情况下称为存根 - 客户端代码需要链接到它,就好像它链接到真正的静态库一样.自动地,将在运行客户端代码时加载dll.当然,操作系统需要通过其查找机制找到dll,这意味着你不能将dll放在任何地方,而是放在特定的位置.这里有更多内容.

一个非常方便的工具,用于查看是否从dll导出了正确的函数,以及客户端代码是否正确导入是dumpbin.分别使用/ EXPORTS和/ IMPORTS运行它.


pae*_*bal 6

QBziZ的答案是对的.请参阅C++中的非托管DLL

要完成它:在C++中,如果需要使用符号,则必须告诉编译器它是否存在,并且通常是它的原型.

在其他语言中,编译器将自己探索库,并找到符号,etvoilà.

在C++中,您必须告诉编译器.

将C/C++标题视为书目目录

最好的方法是在一些常见的地方放置所需的代码."界面",如果你愿意的话.这通常在头文件中完成,称为头文件,因为这通常不是一个独立的源文件.标题只是一个文件,其目的是包含(即由预处理器复制/粘贴)到真正的源文件中.

实质上,似乎你必须声明两次符号(函数,类,等等).与其他语言相比,这几乎是一种异端邪说.

您应该将其视为书籍,包含摘要表或索引.在表格中,您有所有章节.在文中,您有章节及其内容.

有时,你很高兴你有章节清单.

在C++中,这是标题.

那DLL怎么样?

所以,回到DLL问题:DLL的目的是导出代码将使用的符号.

因此,以C++方式,您必须在编译时导出代码(例如,在Windows中,使用__declspec)和"发布"导出内容的表(即具有包含导出声明的"public"头) .