我必须在C ++中创建一个动态DLL库,以替换Fortran编写的旧DLL库,而无需更改主机应用程序(因此函数和参数必须保持不变)。
我对该库中的所有Fortran函数有完整的规范,但是我需要使用哪些工具(编译器),以及在这种情况下编码DLL的方式是什么(stdcall,cdecl,dllexport等等 - 这些线索没有'对我说的很多,我之前从未创建过DLL。
这是旧DLL中的Fortran函数声明示例:
SUBROUTINE SetBoundaries(MaxFlow, MinFlow)
cDEC$ ATTRIBUTES DLLEXPORT :: SetBoundaries
cDEC$ ATTRIBUTES ALIAS: "SetBoundaries" :: SetBoundaries
REAL MaxFlow
REAL MinFlow
我尝试编译VC2008 DLL但出现错误:
'InitAllPublicVars'中未处理的错误运行时错误453:找不到 SomeLib.DLL中的DLL入口点DLLVersion
此DLL的源代码(定义名为DLLVersion的函数无效):
void __stdcall SetBoundaries( float *min , float *max ) {
}
DLLVersion是一些特殊的DLL程序还是只缺少我的文档而我应该创建这样的函数?
我不知道有关原始Fortran DLL源代码/编译过程的详细信息,但有一些提取的信息:
答案 0 :(得分:4)
运行时库使Fortran DLL看起来像是使用Compaq或Digital Fortran编译器构建的。默认情况下,这些编译器使用stdcall调用约定。对于您的具体示例,两个参数(C侧的参数)等效于float *
,子例程等效于void函数。您需要使用支持stdcall的C ++编译器。如何指定函数在DLL中导出取决于您的C ++编译器或个人首选项,但某种dllexport关键字是典型的。
从变更管理的角度来看,在Fortran中编写替换DLL并使用像英特尔Fortran编译器这样的东西要简单得多,后者是CVF编译器的后代,具有适当的遗留支持。然后可以以渐进方式对DLL源代码进行更改。
答案 1 :(得分:2)
我找到了解决方案。 DLL函数应该像这样声明:
extern "C" void __declspec(dllexport) SetBoundaries( int min , int max ) {
}
请注意,参数不是指针。我记录了函数调用,并且当放入而不是原始的Fortran DLL时,DLL从主机应用程序获取有效数字。使用Visual Studio 2008编译。