You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++与FORTRAN混合编程:字符数组跨语言传递问题咨询

解决Fortran向C++传递字符数组的问题

看起来你在Fortran和C++混合编程时卡在了字符数组传递这一步——这俩语言的字符串/数组处理逻辑确实差异不小,尤其是字符串存储和数组内存布局的区别很容易踩坑。我结合你给出的代码片段,整理了一套可行的解决方案,咱们一步步来:

先说说你当前代码的核心问题

你在C++里声明的testchararray(char arr[][10])没有考虑到:

  1. Fortran的字符串是固定长度、不带\0终止符的,而C++默认依赖\0识别字符串结尾;
  2. Fortran传递数组时是列优先存储,和C++的行优先正好相反;
  3. 没有明确传递数组的行数信息,C++没法正确遍历数组;
  4. 直接用默认方式调用的话,Fortran会偷偷给C++函数传递字符串长度的额外参数,导致接口不匹配。

完整解决方案:用ISO_C_BINDING统一接口

Fortran 2003引入的iso_c_binding模块是跨语言交互的标准方案,能完美解决这些兼容性问题,下面是完整的可运行代码:

第一步:调整C++端的DLL代码

CDll.h

// CDll.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define DLLEXPORT __declspec(dllexport)

// 新增rows参数,告诉C++数组有多少行;每个字符串固定10个字符
DLLEXPORT void testchararray(char arr[][10], int rows);

#ifdef __cplusplus
}
#endif

CDll.cpp

// CDll.cpp
#include "CDll.h"
#include <iostream>
#include <cstring>

using namespace std;

void testchararray(char arr[][10], int rows) {
    cout << "从Fortran接收到的字符数组:" << endl;
    for (int i = 0; i < rows; ++i) {
        // 方式1:给Fortran字符串手动加\0,避免乱码
        char temp_str[11];
        strncpy(temp_str, arr[i], 10);
        temp_str[10] = '\0'; // 强制添加终止符
        cout << "第" << i+1 << "行:" << temp_str << endl;

        // 方式2:直接按固定长度输出(会保留Fortran字符串末尾的空格)
        // cout << "第" << i+1 << "行:" << string(arr[i], 10) << endl;
    }
}

第二步:编写Fortran端的调用代码

program call_cpp_char_array
    use, intrinsic :: iso_c_binding  ! 必须引入这个模块做跨语言绑定
    implicit none

    ! 声明和C++函数对应的接口,确保参数类型、名称完全匹配
    interface
        subroutine testchararray(arr, rows) bind(C, name='testchararray')
            import :: c_char, c_int  ! 导入C兼容的类型
            character(kind=c_char), intent(in) :: arr(:,:)  ! 二维字符数组
            integer(kind=c_int), intent(in) :: rows        ! 数组行数
        end subroutine testchararray
    end interface

    ! 定义Fortran本地字符数组:3行,每行10个字符(Fortran是列优先,所以维度是[长度, 行数])
    character(len=10), target :: fortran_arr(3) = ["Hello     ", "World     ", "FortranC++"]
    ! 声明一个C兼容的指针,用来转换Fortran数组的内存布局
    character(kind=c_char), pointer :: c_compatible_arr(:,:)

    ! 将Fortran数组转换为C兼容的内存布局(反转维度:C是[行数, 长度])
    call c_f_pointer(c_loc(fortran_arr), c_compatible_arr, [3, 10])

    ! 调用C++的DLL函数,注意类型要匹配(用_c_int标记整数类型)
    call testchararray(c_compatible_arr, 3_c_int)

end program call_cpp_char_array

关键要点解释

  • iso_c_binding模块:这是跨语言交互的核心,它提供了和C语言一一对应的类型(比如c_char对应C的char,c_int对应C的int),同时通过bind(C)告诉Fortran编译器按照C的规则生成函数调用,避免名称修饰问题。
  • 数组存储顺序:Fortran是列优先(先存第一列的所有元素),C是行优先(先存第一行的所有元素),所以我们用c_f_pointer反转了数组维度,确保C能正确读取每一行的字符串。
  • 字符串终止符:Fortran字符串没有\0,所以在C++里要么手动添加终止符(方式1),要么直接按固定长度读取(方式2),避免输出乱码。
  • 编译链接注意事项:编译时要保证C和Fortran编译器的平台一致(都是x86或x64),Fortran编译时需要链接C生成的DLL库文件。

内容的提问来源于stack exchange,提问作者Blane John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:03:13