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

Passing C++ character array to Fortran

本文关键字:Fortran 数组 C++ 字符      更新时间:2023-10-16

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

下面的函数是我的C++例程,它调用fortran子例程:

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上以查看其内容,但"监视"窗口显示它找不到file_name符号(尽管len已正确传递)。此外,如果我在观察窗口中观察file_name(1:8),仍然无法获得原始的字符数组。我认为将参数传递给Fortran的方式有问题,但"观察窗口"可能不正确。

我很感激任何能给我们带来光明的帮助。感谢

你陷入了陷阱,这是因为你说(即使在投票支持率很高的答案中的堆栈溢出)你应该使用ISO C绑定来构建可互操作的子例程。

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

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

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

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

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