C++ 从 dll 调用 FORTRAN 子例程

Posted

技术标签:

【中文标题】C++ 从 dll 调用 FORTRAN 子例程【英文标题】:C++ calling FORTRAN subroutine from dll 【发布时间】:2015-04-10 12:09:03 【问题描述】:

我必须处理一些非常古老的 FORTRAN 代码,但我想在 C++ 中使用 FORTRAN 中的一些函数。现在我有一个小项目要练习导出 FORTRAN dll 并在 C 中导入它。我在 Windows 上使用 FORTRAN 和 Visual C++ 的 FTN95 编译器进行操作。我的 fortran 源代码包含此功能:

F_STDCALL integer function test_fort(a)
            implicit none
            integer, intent(in) :: a
            test_fort = 2*a
    end function

我将它编译为 FORT.dll,然后将其放入我的 C++ 项目的输出文件夹中。 C++源代码:

#include<stdlib.h>
#include<Windows.h>
#include<stdio.h>

typedef int(__stdcall *test_fort)(int* a);

int main()

    HMODULE hFortDll = LoadLibraryW(L"FORT.dll");

    if (hFortDll == NULL)
        wprintf(L"Error loading FORT.dll");
    else
    
        wprintf(L"Loading successful\r\n");
        FARPROC result = GetProcAddress(hFortDll, "test_fort");
        test_fort fortSubroutine = (test_fort)result;

        if (fortSubroutine == NULL)
            wprintf(L"Function not found\r\n");
        else
            wprintf(L"Function successfully loaded\r\n");

        FreeLibrary(hFortDll);
    

    getchar();

    return 0;

如果我运行这段代码,我会得到以下输出:

Loading successful
Function not found

调试器显示 result 包含零地址 (0x00000000)。我不知道我做错了什么,像this 这样的线程没有提供答案。

提前致谢。

【问题讨论】:

使用 depends (dependencywalker.com) 找出实际调用的 fortran 例程。它可能有前导或尾随下划线,也可能完全大写。 还要小心你使用的是 Unicode - Fortran 通常是 ASCII。 我知道我使用的是 Unicode。但是据我所知,使用 Unicode 加载库是可以的,并且 GetProcAddress 具有 LPCSTR 类型的第二个参数,而不是 LPCWSTR。所以应该没问题,但我会检查 【参考方案1】:

感谢非常快速的响应和指向一个非常有用的工具Dependency Walker 的链接,我发现问题出在函数名称上。虽然我花了一些时间更改“test_fort”的大小写并向其添加诸如“_”之类的符号,但我错过了“TEST_FORT”变体——这是 .dll 中“test_fort”FORTRAN 函数的别名。 所以,为了让它工作,我只需要修改一行代码:

FARPROC result = GetProcAddress(hFortDll, "TEST_FORT");

【讨论】:

以上是关于C++ 从 dll 调用 FORTRAN 子例程的主要内容,如果未能解决你的问题,请参考以下文章

从 C++ 调用带有可选参数的 Fortran 子例程

从 C++ 调用带有可选参数的 Fortran 子例程

如何在由 MPI 并行化的 fortran 中调用子例程?

由 R 调用时,Fortran 子例程不计算

通过在 C++ 接口周围创建 C 包装器,在 FORTRAN 中调用 C++ dll 文件 [关闭]

在 C++ 和 Fortran 代码之间传递复数数组