温馨提示×

Ubuntu中Fortran与MATLAB如何协同工作

小樊
51
2025-10-12 00:23:30
栏目: 编程语言

Ubuntu中Fortran与MATLAB协同工作的实现方法

在Ubuntu系统中,Fortran与MATLAB可通过共享库调用(MATLAB调用Fortran编译的.so文件)或MEX文件(Fortran通过MEX接口集成到MATLAB)两种主要方式协同工作,以下是具体步骤及注意事项:

一、准备工作:安装必要工具

  1. 安装Fortran编译器:Ubuntu默认仓库中的gfortran是开源且兼容性好的选择,通过以下命令安装:
    sudo apt update && sudo apt install gfortran 
  2. 安装MATLAB:从MathWorks官网下载并安装Ubuntu版本的MATLAB,安装完成后确保matlab命令可在终端中运行。
  3. 配置Fortran编译器环境:若使用gfortran,无需额外配置;若使用Intel Fortran Compiler,需通过mex -setup fortran命令让MATLAB识别编译器。

二、方法1:MATLAB调用Fortran编译的共享库(.so文件)

1. 编写Fortran代码

创建Fortran源文件(如my_fortran_lib.f90),编写需要调用的子程序。注意:

  • 子程序需使用intent属性明确参数方向(in/out/inout);
  • 避免使用Fortran特有的屏幕输入输出(如print *),如需调试可使用open()写入文件。
    示例代码:
subroutine add_numbers(a, b, c) real(8), intent(in) :: a, b ! 输入参数 real(8), intent(out) :: c ! 输出参数 c = a + b ! 简单加法运算 end subroutine add_numbers 

2. 编译Fortran代码为共享库

使用gfortran编译为.so文件(Linux下的动态链接库),需添加-shared(生成共享库)、-fPIC(位置无关代码,动态链接必需)选项:

gfortran -shared -fPIC -o libmy_fortran_lib.so my_fortran_lib.f90 

编译成功后,会在当前目录生成libmy_fortran_lib.so文件。

3. 在MATLAB中调用共享库

MATLAB通过calllib函数调用共享库中的子程序,步骤如下:

  • 加载共享库:使用loadlibrary加载.so文件及对应的头文件(需手动创建头文件);
  • 准备输入参数:MATLAB中的变量需转换为Fortran兼容的类型(如real(8)对应MATLAB的double);
  • 调用子程序:使用calllib指定库名、子程序名及参数;
  • 卸载共享库:使用unloadlibrary释放资源。

示例MATLAB代码:

% 定义Fortran子程序的头文件内容(需保存为my_fortran_lib.h) % void add_numbers(double *a, double *b, double *c); % 加载共享库及头文件 if libisloaded('my_fortran_lib') unloadlibrary('my_fortran_lib'); end loadlibrary('libmy_fortran_lib.so', 'my_fortran_lib.h'); % 准备输入参数 a = 3.5; b = 2.5; c = 0; % 输出变量需初始化 % 调用Fortran子程序 calllib('my_fortran_lib', 'add_numbers', a, b, c); % 显示结果 disp(['计算结果: ', num2str(c)]); % 卸载共享库 unloadlibrary('my_fortran_lib'); 

4. 注意事项

  • 头文件创建:若Fortran子程序未自动生成头文件,需手动创建(如my_fortran_lib.h),内容为子程序的C风格声明(void add_numbers(double *a, double *b, double *c););
  • 数据类型匹配:Fortran的real(8)对应MATLAB的doubleinteger对应MATLAB的int32/int64
  • 路径配置:将共享库所在目录添加到LD_LIBRARY_PATH环境变量(如export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library),避免MATLAB找不到库文件。

三、方法2:通过MEX文件集成Fortran代码

MEX文件(MATLAB Executable)是MATLAB可调用的动态链接库,允许Fortran代码直接在MATLAB中运行。适用于需要复用现有Fortran代码或与MATLAB深度交互的场景。

1. 编写Fortran MEX接口代码

MEX文件需包含mexFunction入口点(类似C的main函数),并通过MATLAB API实现数据传递。示例代码(my_fortran_mex.f90):

subroutine mexFunction(nlhs, plhs, nrhs, prhs) use mex implicit none integer, intent(in) :: nlhs, nrhs ! 输出/输入参数数量 type(mxArray), intent(out) :: plhs(nlhs) ! 输出参数 type(mxArray), intent(in) :: prhs(nrhs) ! 输入参数 real(8) :: a, b, c ! Fortran变量 mwPointer :: mx_a, mx_b, mx_c ! mxArray指针 ! 检查输入输出数量 if (nrhs /= 2) then call mexErrMsgIdAndTxt('MATLAB:fortran_mex:invalidInput', '需2个输入参数'); elseif (nlhs > 1) then call mexErrMsgIdAndTxt('MATLAB:fortran_mex:invalidOutput', '最多1个输出参数'); end if ! 从输入参数获取数据(mxArray转Fortran变量) mx_a = prhs(1); a = mxGetScalar(mx_a); mx_b = prhs(2); b = mxGetScalar(mx_b); ! 调用Fortran计算子程序 call add_numbers(a, b, c) ! 创建输出mxArray并赋值 plhs(1) = mxCreateDoubleScalar(c) end subroutine mexFunction subroutine add_numbers(a, b, c) real(8), intent(in) :: a, b real(8), intent(out) :: c c = a + b end subroutine add_numbers 

2. 编译MEX文件

在MATLAB中编译Fortran MEX文件,需确保mex能识别Fortran编译器(通过mex -setup fortran配置):

mex -v my_fortran_mex.f90 

编译成功后,会在当前目录生成my_fortran_mex.mexa64文件(Ubuntu下的MEX文件扩展名)。

3. 在MATLAB中调用MEX文件

MEX文件可直接像MATLAB内置函数一样调用:

a = 3.5; b = 2.5; result = my_fortran_mex(a, b); % 调用Fortran MEX文件 disp(['计算结果: ', num2str(result)]); 

4. 注意事项

  • MEX接口规范mexFunction的参数顺序固定(nlhsplhsnrhsprhs),需严格遵循;
  • 内存管理mxArray是MATLAB的内存对象,需通过mxCreate*创建、mxDestroyArray释放,避免内存泄漏;
  • 数据转换:使用mxGetScalar(获取标量)、mxGetPr(获取数组指针)等API函数实现Fortran与MATLAB数据转换。

四、常见问题解决

  1. 共享库加载失败:检查LD_LIBRARY_PATH是否包含共享库路径,或使用addpath将路径添加到MATLAB搜索路径;
  2. 数据类型不匹配:确保Fortran中的real(8)与MATLAB的double对应,数组维度需一致;
  3. MEX编译错误:确认mex -setup fortran已正确配置Fortran编译器,且Fortran代码符合MEX接口规范。

通过上述方法,可在Ubuntu系统中实现Fortran与MATLAB的高效协同,结合Fortran的高性能计算与MATLAB的便捷数据处理、可视化功能,满足科学计算与工程应用的需求。

0