能否将C++指针向量传递给Fortran DLL?
如何将C++的指针向量传递给Fortran DLL?
你的思路方向是对的,但当前代码存在类型不匹配的核心问题——Fortran端期望接收一个普通浮点数组,而C++传递的是一个指针数组(std::vector<float*>),两者的内存布局和类型完全不兼容。下面是修正后的完整实现方案:
问题根源
你当前的Fortran代码中,test4被声明为REAL, intent(in) :: test4(3),这表示接收的是3个连续的浮点值;但C++端传递的std::vector<float*>本质是一个存储了3个float*指针的数组,每个指针指向独立的浮点数组。直接传递会导致Fortran把指针值当成浮点数据读取,必然引发错误。
修正后的Fortran DLL代码
我们需要调整Fortran的参数类型,让它能接收C风格的指针数组,再逐个转换为Fortran可操作的指针:
!DEC$ATTRIBUTES DLLEXPORT :: TO_FORTRAN integer function TO_FORTRAN(test4) BIND(C) use, intrinsic :: ISO_C_BINDING implicit none ! 声明参数为C风格的指针数组(对应C++的float**) TYPE(C_PTR), intent(in) :: test4(3) REAL(C_FLOAT), pointer :: test5(:) integer :: i do i = 1, 3 ! 将每个C指针转换为Fortran可寻址的指针 ! 这里假设每个指针指向长度为3的浮点数组,你可以根据实际情况调整 call C_F_POINTER(test4(i), test5, [3]) ! 这里可以添加对test5的操作,比如打印验证 print *, "Array ", i, ": ", test5(1), test5(2), test5(3) end do TO_FORTRAN = 0 end function TO_FORTRAN
修正后的C++调用代码
C++端需要正确传递指针数组的地址,同时要声明Fortran函数的C兼容接口:
#include <vector> // 声明Fortran DLL导出的函数(注意extern "C"避免名字 mangling) extern "C" int TO_FORTRAN(float** test4); int main() { std::vector<float> test1 = {1.0f, 2.0f, 3.0f}; std::vector<float> test2 = {4.0f, 5.0f, 6.0f}; std::vector<float> test3 = {7.0f, 8.0f, 9.0f}; std::vector<float*> test4 = {test1.data(), test2.data(), test3.data()}; ! 传递指针数组的底层地址(对应Fortran的C_PTR数组) TO_FORTRAN(test4.data()); return 0; }
关键注意事项
- 类型匹配:
BIND(C)要求Fortran和C++的参数类型严格对应,TYPE(C_PTR)对应C的void*,这里我们用float**传递,所以Fortran接收C_PTR数组是正确的。 - 数组维度:
C_F_POINTER的第三个参数指定了Fortran指针指向的数组维度,必须和C++端数组的实际长度一致,否则会越界访问。 - 名字修饰:C++中必须用
extern "C"声明Fortran函数,避免编译器对函数名进行mangling,确保能正确找到DLL中的导出函数。
内容的提问来源于stack exchange,提问作者Sam van der Zwan
相关产品推荐
相关产品推荐

