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

如何通过MEX在MATLAB中无拷贝访问Fortran变量?

在Fortran MEX函数中无拷贝只读访问MATLAB多维数组

核心思路

MATLAB的数组内存采用列优先存储(和Fortran完全一致),因此可以直接获取其数据区的指针,通过Fortran的ISO_C_BINDING模块将C风格指针转换为Fortran可直接访问的数组指针,全程无需拷贝内存。

实现步骤与代码示例

1. 基础输入参数场景(MEX函数接收输入数组)

以下是一个完整的Fortran MEX函数示例,实现只读访问输入的二维双精度数组,计算所有元素的和:

#include "fintrf.h"

      subroutine mexFunction(nlhs, plhs, nrhs, prhs)
          use, intrinsic :: ISO_C_BINDING
          implicit none
          ! MEX接口标准参数
          mwPointer :: plhs(*), prhs(*)
          integer :: nlhs, nrhs
          ! 局部变量
          mwPointer :: mx_input, data_ptr
          integer :: array_dims(2)
          real(c_double), pointer :: matlab_array(:,:)
          real(c_double) :: total_sum

          ! 校验输入参数数量
          if (nrhs /= 1) then
              call mexErrMsgIdAndTxt('MATLAB:NoCopyRead:BadInputCount', &
                  '错误:仅需传入一个输入数组')
          end if

          ! 获取输入数组的mxArray指针
          mx_input = prhs(1)

          ! 校验数组类型(仅支持实双精度数组)
          if (.not. mxIsDouble(mx_input) .or. mxIsComplex(mx_input)) then
              call mexErrMsgIdAndTxt('MATLAB:NoCopyRead:InvalidType', &
                  '错误:输入必须是实双精度数组')
          end if

          ! 获取数组维度信息
          call mxGetDimensions(mx_input, array_dims)

          ! 获取MATLAB数组数据区的指针(无拷贝)
          data_ptr = mxGetData(mx_input)

          ! 将C风格指针转换为Fortran可直接访问的数组指针
          call c_f_pointer(c_loc(data_ptr), matlab_array, [array_dims(1), array_dims(2)])

          ! 只读访问数组,执行计算
          total_sum = 0.0d0
          do j = 1, array_dims(2)
              do i = 1, array_dims(1)
                  total_sum = total_sum + matlab_array(i,j)
              end do
          end do

          ! 创建输出结果
          plhs(1) = mxCreateDoubleScalar(total_sum)
      end subroutine mexFunction

2. 访问MATLAB工作区变量场景

如果需要访问的是MATLAB工作区中的变量(而非MEX函数的输入参数),可以用mexGetVariablePtr获取指针,后续转换逻辑一致:

! 获取工作区中名为"my_array"的变量指针
data_ptr = mexGetVariablePtr('caller', 'my_array')
! 后续同样用c_f_pointer转换为Fortran数组指针

关键说明

  • 内存安全:通过这种方式获取的指针指向MATLAB管理的内存,绝对不可修改数组内容,否则会破坏MATLAB的内存管理机制,导致崩溃或数据损坏。
  • 维度匹配:MATLAB数组是列优先存储,与Fortran完全兼容,转换时直接使用mxGetDimensions返回的维度即可,无需调整顺序。
  • 复数数组处理:如果是复数数组,需分别用mxGetData获取实部指针、mxGetImagData获取虚部指针,再分别转换为Fortran数组指针。
  • 编译方式:使用MATLAB的mex命令编译代码,例如:mex no_copy_read.f90(假设代码文件名为no_copy_read.f90)。

内容的提问来源于stack exchange,提问作者Vinicius Oliveira Fontes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:54:52