1)使用vc6 编写动态库,动态库源码 (dll_test.cpp) 如下:
#include <windows.h>
// _declspec(dllexport) means test() can be called by others
void _declspec(dllexport) test()
{
MessageBox(NULL, "call test() success!", "test", MB_OK);
}
BOOL APIENTRY DllMain(HANDLE a, DWORD b, LPVOID c)
{
MessageBox(NULL, "in DllMain", "main", MB_OKCANCEL);
return TRUE;
}
生成动态库为 dll_test.dll,把它放到添加到系统可以找到的目录
在“运行中调用”
rundll32 dll_test.dll,test
有如下错误提示
使用 depends 分析原因
发现在 导出的函数名前后都有乱码,将其复制后,再次执行
rundll32 dll_test.dll,?test@@YAXXZ
2)修改源码,如下:
#include <windows.h>
// _declspec(dllexport) means test() can be called by others
extern "C" void _declspec(dllexport) test()
{
MessageBox(NULL, "call test() success!", "test", MB_OK);
}
BOOL APIENTRY DllMain(HANDLE a, DWORD b, LPVOID c)
{
MessageBox(NULL, "in DllMain", "main", MB_OKCANCEL);
return TRUE;
}
编译生成动态库后,通过 depends 查看:
同时使用 rundll32 dll_test.dll,test 进行测试,有正确结果如下:
3)原因分析
extern "C" 是告诉编译器用C语言的方式给函数命名。在用VC制作DLL导出函数时,由于C++存在函数重载,为了
实现同样的函数名可因参数不同而存在,所以在VC处理这些函数时,会把函数名编译成不同的名字以便自己识别。
例如:
int test(int, int) -> test@@YAHHH@Z
float test(float, float) -> test@@YAMMM@Z
但当我们使用 extern "C" 时,编译器会标识为: _函数名
int test(int, int) -> _test
float test(float, float) -> _test
因此被 extern "C" 修饰过的函数不再具备重载能力。
原文链接: https://www.cnblogs.com/aqing1987/p/4596893.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/218123
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!