C++如何导出dll
DLL 是一个包含可由多个程序同时使用的代码和数据的库。 例如,在 Windows 操作系统中,Comdlg32 DLL 执行与对话框有关的常见函数。 因此,每个程序都可以使用该 DLL 中包含的功能来实现“打开”对话框。 这有助于促进代码重用和内存的有效使用。
通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。 例如,一个计帐程序可以按模块来销售。 可以在运行时将各个模块加载到主程序中(如果安装了相应模块)。 因为模块是彼此独立的,所以程序的加载速度更快,而且模块只在相应的功能被请求时才加载。
c++调用.lib的方法
隐式加载

显式加载

函数的导出方式
使用exten “C” C语言方式导出
extern "C"
的作用是声明以c语言的格式编译当前代码:
c语言没有函数重载
编译后的函数名若有参数以”xxx@数字”结尾,“数字”为所有参数占用的内存大小(4位对齐);若无参数则结尾不含”@数字”
编译后的开头字符与调用约定__cdecl(无开头字符)、__**stdcall(以‘_’开头)、__fastcall(以‘@’开头)**有关
网络上大部分资料都是使用这种方式。
使用C++方式导出
默认情况下,不加extern "C"
,将使用C++方式导出;
Demo示例
1 | //calc.cpp |
1 | //calc.h |
查看dll–使用Dependencies
Dependencies github地址:
查看dll
C++ 显示调用dll
- demo:
1 |
|
- 编译运行报错

因为c++函数名导出方式,add()函数的函数名不是叫add,所有无法找到这个函数。
使用Dependencies打开dll文件,查看add()函数的c++导出函数名,修改重新编译运行:

修改之后,函数add()可以找到了,但是运行抛异常了;分析之后发现,是因为C++所有的成员函数中都有一个隐含的this指针,所以此处add应该有三个参数,直接传递两个参数,是非法传参。
解决方法:将add()函数定义为static函数:

编译运行,再次报错:找不到add()函数:

因为修改了函数为static,所有c++导出的add()函数名发生了变化,修改后重新编译正常:

这样的函数名使用起来总是有些不方便,要使用和代码相同的常规的函数名,一般有两种方法:
- 声明为
exten "C"
,表示使用C语言方式编译,但是对于一些函数需要c++特性,比如C++的变量类型,C++的重载等,这样就没法实现; - 链接时使用def文件,指定函数的名字;
使用def文件生成常规名字的dll
1 | LIBRARY dll_export_demo |

vs链接器配置:

重新编译,查看dll:

直接使用add函数名重新编译运行,工作正常:

参考引用
https://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html
https://blog.csdn.net/lwwl12/article/details/86655488
https://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/fatal-error-c1010?view=vs-2019