C++中如何将运行时确定形状的二维数组传给外部Fortran函数
动态确定二维数组形状并调用Fortran外部函数
问题背景
现有C++程序调用Fortran外部函数fortfunc_,当前代码中二维数组的第二维度为硬编码值,仅能在运行时动态确定第一维度。需要修改程序,让二维数组foo的两个维度都能在运行时动态确定,同时正常调用Fortran函数。
修改方案
1. C++端修改
核心思路是用动态分配的一维数组模拟二维数组(避免非标准的变长数组VLA),同时调整外部函数的声明为指针形式,适配动态内存布局:
#include <iostream> using namespace std; // 外部函数声明改为指针接收数组,适配动态维度 extern"C" { void fortfunc(int* a, int* size_x, int* size_y); } int main() { // 运行时动态确定的维度(示例直接赋值,实际可从输入/计算获取) int size_x = 5; int size_y = 4; // 动态分配连续内存,大小为两个维度的乘积 int* foo = new int[size_x * size_y]; // 按行优先填充数组:foo[i * size_y + j] 等价于原二维数组的 foo[i][j] for (int i=0 ; i<size_x ; i++ ) { for (int j=0 ; j<size_y ; j++ ) { foo[i * size_y + j] = i + j; } } // 调用Fortran函数,传递数组指针和维度参数 fortfunc(foo, &size_x, &size_y); // 释放动态分配的内存 delete[] foo; return 0; }
2. Fortran端修改
使用bind(C)属性规范函数命名(避免编译器自动加下划线的依赖),同时保持数组维度定义适配C的内存布局(Fortran为列主序,对应C的行主序二维数组转置后的维度):
subroutine fortfunc(foo, size_x, size_y) bind(C, name='fortfunc') use :: ISO_C_BINDING integer(c_int), intent(in) :: size_x, size_y ! 维度对应C的size_y列、size_x行,匹配C的行优先内存布局 integer(c_int), dimension(size_y, size_x), intent(in) :: foo integer :: i, y do y = 1, size_x do i = 1, size_y print*, "col ", i, y, foo(i,y) end do print*, "row" end do end subroutine fortfunc
编译运行命令
执行以下命令完成编译和运行:
gfortran -c testF.f90 && g++ -c testC.cpp && g++ -o test testF.o testC.o -lgfortran && ./test
关键说明
- C++中用一维数组模拟二维数组,确保内存连续,适配Fortran的列主序内存布局;
- Fortran使用
bind(C)属性统一函数名,避免不同编译器的名字修饰差异; - 数组维度对应关系:C的
size_x行、size_y列,对应Fortran的size_y列、size_x行,保证内存元素一一映射。
内容的提问来源于stack exchange,提问作者Yes
相关产品推荐
相关产品推荐

