VS编译Fortran DLL从32位迁移到64位报LNK2019未解析外部符号错误怎么办
问题原因
- 核心问题是代码中硬编码了仅适用于32位平台的函数别名:
!DEC$ ATTRIBUTES ALIAS: '_SELECT@4' :: SELECT。该别名遵循32位Windows下STDCALL调用约定的命名修饰规则:函数名前加下划线,后缀加@+参数栈总字节数,此处单个4字节整型参数对应的后缀为@4。但64位Windows平台的调用约定没有这种命名修饰规则,强制指定别名后,DLL导出的函数名是_SELECT@4,而64位主程序默认查找的符号是SELECT,因此触发链接器符号未找到错误。 - 附加说明:64位Windows平台下,STDCALL、CDECL等调用约定已经统一为微软x64默认调用约定,额外指定STDCALL属性在64位编译下无实际作用,也不会产生对应的命名修饰。
解决方案
- 方案1:直接移除硬编码的ALIAS属性行,让编译器根据当前编译平台自动生成正确的导出符号名,修改后的子例程代码如下:
SUBROUTINE SELECT( i ) !DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: SELECT !DEC$ ATTRIBUTES REFERENCE :: i integer*4 :: i END SUBROUTINE SELECT
- 方案2:如果需要同时兼容32位和64位编译,给ALIAS属性增加平台条件编译判断,只在32位编译时启用该别名,示例如下:
SUBROUTINE SELECT( i ) !DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: SELECT #IF _WIN32 !DEC$ ATTRIBUTES ALIAS: '_SELECT@4' :: SELECT #ENDIF !DEC$ ATTRIBUTES REFERENCE :: i integer*4 :: i END SUBROUTINE SELECT
- 验证方法:编译完成后可以执行
dumpbin /exports 你的DLL文件名.dll命令查看导出函数列表,确认导出的函数名为SELECT即可。
内容的提问来源于stack exchange,提问作者Riccardo
相关产品推荐
相关产品推荐

