提问人:Santosh Tiwari 提问时间:10/21/2013 更新时间:10/22/2013 访问量:1885
Fortran 和 C++:Visual Studio 中的链接错误
Fortran and C++: Linking error in Visual Studio
问:
系统: Windows-7-64-bit/Visual-Studio-2010/Intel-Visual-Fortran-11.
我正在创建 32 位可执行文件。
Fortran 例程声明
SUBROUTINE LA01BD(N,M,L,A,B,C,X,F,IA,IPRINT,IND,WK,IER)
!DEC$ ATTRIBUTES DLLEXPORT::LA01BD
!DEC$ ATTRIBUTES STDCALL,REFERENCE,ALIAS:"LA01BD"::LA01BD
use, intrinsic :: ISO_C_BINDING
C++ 函数签名声明
extern "C" {void __stdcall LA01BD(int *N, int *M, int *L, double *A, double *B, double *C, double *X, double *F, int *IA, int *IPRINT, int *IND, double *WK, int *IER); }
我使用 Visual Studio 2010 和英特尔 Visual Fortran 编译器 11 从 fortran 代码创建了 dll。我在依赖遍历器中检查了导出的symobol,函数是“LA01BD”。
在我的 C++ 项目中使用相同的 dll(链接期间的 .lib 文件)时,我收到以下链接器错误。
lpwrap.obj : error LNK2001: unresolved external symbol _LA01BD@52
我无法解决此问题。后缀“@52”有什么作用?如何解决链接问题?
谢谢。
答:
0赞
Matt
10/22/2013
#1
这是由名称篡改引起的,详情请参考。我猜你错过了 C++ 项目中的外部“c”。
评论
0赞
Santosh Tiwari
10/22/2013
在头文件中声明 fortran 函数时,我确实使用了 extern“C”。
3赞
Hans Passant
10/22/2013
#2
C++ 编译器将名称修饰应用于标识符。__stdcall装饰是前导_underscore和尾随@n,其中 n 是激活帧的大小。
Fortran 代码中的 ALIAS 指令导致了此问题,您强制将其导出为“LA01BD”而不是“_LA01BD@52”。您应该首先尝试将其删除,以便应用正常的名称修饰。如果这不是一个选项,则需要从正确构建的 .def 文件使用 lib.exe /def 创建导入库,或者使用 GetProcAddress() 回退到后期绑定。
评论
0赞
Santosh Tiwari
10/22/2013
我删除了它(包含别名的整行),但仍然收到相同的错误。
0赞
Hans Passant
10/22/2013
您实际上是否链接了导入库?用 Dumpbin.exe /all 查看它里面有什么。并删除删除整行,只删除 ALIAS。
0赞
Santosh Tiwari
10/22/2013
我从 .h 文件中的声明中删除了 __stdcall,它起作用了。
1赞
Hans Passant
10/22/2013
这是因为您删除了整行,而不仅仅是 ALIAS。
0赞
Santosh Tiwari
10/22/2013
谢谢。我现在只有DLLEXPORT属性。我摆脱了其他所有东西,它起作用了(构建成功)。
2赞
IanH
10/22/2013
#3
如果必须使用 STDCALL 调用约定,则将 DECORATE 属性添加到 Fortran 端,以指示编译器修饰指定的别名。
SUBROUTINE LA01BD(N,M,L,A,B,C,X,F,IA,IPRINT,IND,WK,IER)
!DEC$ ATTRIBUTES DLLEXPORT::LA01BD
!DEC$ ATTRIBUTES STDCALL,REFERENCE,ALIAS:"LA01BD"::LA01BD
!DEC$ ATTRIBUTES DECORATE :: LA01BD
评论
0赞
Santosh Tiwari
10/22/2013
谢谢。我不知道。
评论