Fortran在两个C函数之间传递C struct
我有一个Fortran应用程序,需要调用两个C例程。 一个用于加载文件,另一个用于对文件运行大约200次计算。 我知道C DLL无法将加载的结构“保存”在静态变量中,以便在计算函数中重用,因此我希望将void*解析回Fortran并将其发送给C计算函数 C功能:Fortran在两个C函数之间传递C struct,c,fortran,interop,fortran-iso-c-binding,C,Fortran,Interop,Fortran Iso C Binding,我有一个Fortran应用程序,需要调用两个C例程。 一个用于加载文件,另一个用于对文件运行大约200次计算。 我知道C DLL无法将加载的结构“保存”在静态变量中,以便在计算函数中重用,因此我希望将void*解析回Fortran并将其发送给C计算函数 C功能: __declspec(dllexport) void loadfile(void * file); // Empty pointer should be filled with struct of loaded file __de
__declspec(dllexport) void loadfile(void * file); // Empty pointer should be filled with struct of loaded file
__declspec(dllexport) void calculate(void * file, double * result); //filled void ptr is used (casted back to my struct first)
我的Fortran代码:
加载文件例程:
SUBROUTINE loadcfile()
USE, INTRINSIC::ISO_C_BINDING
use globalFileHolder
IMPLICIT NONE
INTERFACE
SUBROUTINE loadfile(fm) BIND(C)
USE, INTRINSIC::ISO_C_BINDING
TYPE(C_PTR) :: fm
END SUBROUTINE loadfile
END INTERFACE
TYPE(C_PTR) :: fms = c_null_ptr
call loadfile(fms)
fileModule = fms
return
end
最后,我的例程应该在计算中使用加载的文件:
现在我遇到的问题是,模块变量filemodule似乎已填充,但当将其发送到计算函数时,该变量在强制转换后为null,如下所示:
myStruct * ms = (myStruct*)file;
哪里出错?loadfile接口中的
fm
伪参数声明缺少VALUE属性。您好,感谢您的贡献,添加VALUE属性确实修复了一个部分。文件现在确实正确地返回到函数,但计算函数仍然接收NULL作为数据*编辑:可能是将其存储在例程之间的模块中是个问题吗?正如所提供的(以及根据francescalus在问题下的评论),loadfile
C函数无法将信息返回到Fortran端。fms
的值在调用loadfile期间始终保持C_NULL_PTR。你确定你的C原型是正确的吗?你在calculate的res参数上还有一个额外的VALUE属性。res
是否意味着是calculate
的输出?它有value
属性,但实际参数result
在调用之前没有定义它的值。@francescalus确实如此,我已经更改了它。但问题在于,如果不通过load file函数访问加载的文件,就永远无法计算res。在检查fms(文件模块)是否已正确发送到C计算函数之前,我从不计算res(如:其始终为空)
SUBROUTINE calculatec()
USE, INTRINSIC::ISO_C_BINDING
use globalFileHolder
IMPLICIT NONE
INTERFACE
SUBROUTINE calculate(fm,res) BIND(C)
USE, INTRINSIC::ISO_C_BINDING
TYPE(C_PTR) , VALUE :: fm
REAL(C_DOUBLE) , value :: res
END SUBROUTINE calculate
END INTERFACE
TYPE(C_PTR) :: fms
REAL(C_DOUBLE) result
fms = C_LOC(fileModule)
call calculate(fms,result)
return
end
myStruct * ms = (myStruct*)file;