使用 __declspec(dllexport) 从 DLL 导出

Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib 文件中。然后,此 .lib 文件就可以像静态 .lib 那样用于与 DLL 链接。

在更新的编译器版本中,可以使用 __declspec(dllexport) 关键字从 DLL 导出数据、函数、类或类成员函数。__declspec(dllexport) 会将导出指令添加到对象文件中,因此您不需要使用 .def 文件。

当试图导出 C++ 修饰函数名时,这种便利最明显。由于对名称修饰没有标准规范,因此导出函数的名称在不同的编译器版本中可能有所变化。如果使用 __declspec(dllexport),仅当解决任何命名约定更改时才必须重新编译 DLL 和依赖 .exe 文件。

许多导出指令(如序号、NONAME 和 PRIVATE)只能在 .def 文件中创建,并且必须使用 .def 文件来指定这些属性。不过,在 .def 文件的基础上另外使用 __declspec(dllexport) 不会导致生成错误。

若要导出函数,__declspec(dllexport) 关键字必须出现在调用约定关键字的左边(如果指定了关键字)。例如:

__declspec(dllexport) void __cdecl Function1(void);

若要导出类中的所有公共数据成员和成员函数,关键字必须出现在类名的左边,如下所示:

class __declspec(dllexport) CExampleExport : public CObject
{ ... class definition ... };

生成 DLL 时,通常创建一个包含正在导出的函数原型和/或类的头文件,并将 __declspec(dllexport) 添加到头文件中的声明中。若要提高代码的可读性,请为 __declspec(dllexport) 定义一个宏并对正在导出的每个符号使用该宏:

#define DllExport   __declspec( dllexport ) 

__declspec(dllexport) 将函数名存储在 DLL 的导出表中。如果希望优化表的大小,请参见按序号而不是按名称从 DLL 导出函数

Note注意

将 DLL 源代码从 Win16 移植到 Win32 时,请用 __declspec(dllexport) 替换 __export 的每个实例。

作为参考,请在 Win32 Winbase.h 头文件中搜索。它包含 __declspec(dllimport) 的用法示例。

 
好的,以下是一个使用__declspec(dllexport)导出函数的例子: 首先,我们需要创建一个C++源文件,例如test.cpp,包含以下函数的实现: ```c++ #include <iostream> extern "C" __declspec(dllexport) int add(int a, int b) { return a + b; } extern "C" __declspec(dllexport) void print_name() { std::cout << "My name is ChitGPT!" << std::endl; } ``` 这里使用了extern "C"修饰函数,以确保函数以C语言的命名约定导出。然后,使用__declspec(dllexport)修饰函数,以将其导出DLL导出项。 然后,我们可以使用编译器将其编译为动态链接库,例如在Windows上使用Visual Studio编译器,我们可以使用以下命令: ``` cl /LD test.cpp ``` 这将生成一个名为test.dll的动态链接库文件。 最后,我们可以在另一个C++程序使用test.dll函数,例如: ```c++ #include <iostream> #include <Windows.h> typedef int (*AddFunc)(int, int); typedef void (*PrintNameFunc)(); int main() { HMODULE testDll = LoadLibrary("test.dll"); if (testDll == NULL) { std::cout << "Failed to load test.dll" << std::endl; return 1; } AddFunc add = (AddFunc)GetProcAddress(testDll, "add"); if (add == NULL) { std::cout << "Failed to get address of add function" << std::endl; return 1; } std::cout << "1 + 2 = " << add(1, 2) << std::endl; PrintNameFunc printName = (PrintNameFunc)GetProcAddress(testDll, "print_name"); if (printName == NULL) { std::cout << "Failed to get address of print_name function" << std::endl; return 1; } printName(); FreeLibrary(testDll); return 0; } ``` 这个程序首先使用LoadLibrary函数加载test.dll动态链接库,然后使用GetProcAddress函数获取test.dll的add和print_name函数的地址,并调用它们。最后,使用FreeLibrary函数卸载动态链接库。 这就是一个使用__declspec(dllexport)导出函数的例子。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值