将 C++ 字符数组传递给 Fortran

Posted

技术标签:

【中文标题】将 C++ 字符数组传递给 Fortran【英文标题】:Passing C++ character array to Fortran 【发布时间】:2015-07-02 04:04:49 【问题描述】:

我一直在尝试将字符数组从 C++ 传递到 Fortran 子例程,但似乎 Fortran 无法正确接收字符。我一直在网上搜索以找到解决方案,但提出的想法似乎太复杂了。 Steve 在Intel Fortran Forum 提出了一个有趣(且简洁)的解决方案,但我无法在我的代码中使用它。因此,我感谢任何可以帮助我解决此问题的建议。

以下函数是我调用 fortran 子例程的 C++ 例程:

extern "C" void __stdcall F_VALIDATE_XML(const char* buffer, int len);
void CUDMEditorDoc::OnValidateXML()

    CString fileName = "test.udm";
    const char* buffer = fileName.GetBuffer();
    int len = fileName.GetLength();
    F_VALIDATE_XML(buffer, len);

这是应该接收字符数组的 Fortran 子程序:

subroutine validate_xml(file_name, len)
!DEC$ ATTRIBUTES DECORATE, STDCALL, ALIAS:"F_VALIDATE_XML" :: validate_xml

use xml_reader_structure
use, intrinsic :: ISO_C_Binding

integer(C_INT), value, intent(in) :: len
character(len, kind=C_CHAR), intent(in) :: file_name

integer  :: i
i = 1
end subroutine validate_xml

在调试模式下,当程序停止在行 (i = 1) 时,我将鼠标悬停在 file_name 上以查看其内容,但 Watch 窗口显示找不到 file_name 符号(尽管 len 是正确通过)。另外,如果我在观察窗口中观看file_name(1:8),我仍然没有得到原始字符数组。我相信我将参数传递给 Fortran 的方式有问题,但很可能 Watch Window 不正确。

我很感激任何可以在这里阐明一些信息的帮助。 谢谢

【问题讨论】:

【参考方案1】:

你掉进了陷阱,这是因为你说应该使用 ISO C 绑定来构建可互操作的子例程(即使是在 Stack Overflow 上的大量赞成答案)。

这是错误的,使用iso_c_binding 模块不会使过程具有互操作性,也不会改变调用约定。

Fortran 2003 与 C 互操作性中另一个独立且同样重要的特性是 bind(C) 属性。

请注意,Steve Lionel 在链接示例中有它。你应该有

   subroutine validate_xml(file_name, len) bind(C, name="F_VALIDATE_XML")

bind(C) 以几种微妙的方式改变了调用约定,最大的区别在于字符串,它通常在隐藏参数中传递长度,而不是在可互操作的过程中。

【讨论】:

以上是关于将 C++ 字符数组传递给 Fortran的主要内容,如果未能解决你的问题,请参考以下文章

无法将二维字符数组传递给函数(C++)

将 C# 字符串数组传递给 C++

如何创建接口以将 c 字符数组转换为 fortran

将字符串数组作为缓冲区传递给 C++ 到 C#

将二维字符串数组传递给函数时出错 (C++)

C++ 数组与字符串⁽²³⁾|函数与数组