我一直在尝试将字符数组从C ++传递给Fortran子例程,但似乎Fortran没有正确接收字符。我一直在网上寻找解决方案,但提出的想法似乎太复杂了。史蒂夫在Intel Fortran Forum提出了一个有趣(简洁)的解决方案,但我无法在我的代码中使用它。所以,我感谢任何帮助我解决这个问题的建议。
以下函数是我的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
上以查看其内容,但Watch窗口显示无法找到file_name
符号(尽管len
已正确传递)。另外,如果我在观看窗口中观看file_name(1:8)
,我仍然无法获得原始字符数组。我认为将参数传递给Fortran的方式有问题,但Watch Window的可能性不大。
我感谢任何可以在这里发光的帮助。 感谢
答案 0 :(得分:4)
你陷入了陷阱,这是因为你应该使用ISO C绑定来构建可互操作的子程序(即使在Stack Overflow的大量上升答案中)。
这是错误的,使用iso_c_binding
模块不会使过程可互操作,也不会更改调用约定。
Fortran 2003到C互操作性中另一个独立且同样重要的特性是bind(C)
属性。
注意,史蒂夫莱昂内尔在链接的例子中有它。你应该
subroutine validate_xml(file_name, len) bind(C, name="F_VALIDATE_XML")
bind(C)
以几种微妙的方式更改调用约定,最大的区别在于字符串,通常在隐藏参数中传递长度,但不能在可互操作的过程中传递。