VS2015生成的Win32静态库DLL无法在MASM中导入调用
解决MASM调用Win32 DLL的LNK2019链接错误
我来帮你搞定这个链接错误的问题,咱们先搞明白为什么会出错,再一步步解决。
问题根源
你在VS里编译的DLL导出的是**__stdcall**调用约定的get_key函数,但MASM代码里用了PROTO C——这个C对应的是cdecl调用约定,两者的名字修饰规则不一样,导致链接器找不到匹配的符号。
具体来说,extern "C" + __stdcall的组合下,函数的修饰名会变成_函数名@参数总字节数。你的get_key只接受一个int参数(4字节),所以导出的符号实际是_get_key@4;但MASM里用PROTO C会生成对_get_key的引用,链接器自然找不到这个符号,就报了LNK2019错误。
具体解决方案
方案一:修改MASM的函数声明为stdcall调用约定
直接把MASM里的PROTO声明改成STDCALL,MASM会自动帮你处理名字修饰:
includelib MyLib.lib get_key PROTO STDCALL :DWORD
调用的时候还是用原来的写法就行,MASM会自动转换成_get_key@4的引用,和DLL导出的符号匹配:
push eax invoke get_key, doamne_ajuta
方案二:直接使用修饰后的符号名声明(更直观)
如果你想明确指定符号名,可以直接用导出的修饰名来声明PROTO:
includelib MyLib.lib _get_key@4 PROTO :DWORD
调用的时候也要用这个名字:
push eax invoke _get_key@4, doamne_ajuta
可选:验证DLL的导出符号
你可以用VS自带的dumpbin工具确认DLL导出的符号名,确保我们的分析正确:
打开VS命令提示符,运行以下命令:
dumpbin /exports MyLib.dll
输出里应该能看到类似这样的内容:
ordinal hint RVA name 1 0 00011005 _get_key@4 = @ILT+0(_get_key@4)
这就确认了导出的符号确实是_get_key@4。
额外的代码规范建议
你的DLL代码里有个小冗余:extern "C"块里的__declspec(dllexport) extern重复了,extern在这里没必要,改成下面这样更规范,不影响功能:
MyLib.h
#pragma once #include <conio.h> extern "C" { __declspec(dllexport) int __stdcall get_key(int a); }
MyLib.cpp
#include "stdafx.h" #include "MyLib.h" extern "C" { __declspec(dllexport) int __stdcall get_key(int a) { int c = 0; if (_kbhit()) { c = _getch(); return(c); } a = c; return c; } }
内容的提问来源于stack exchange,提问作者Ioana Cheres
相关产品推荐
相关产品推荐

