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

C++调用Fortran子程序时出现链接错误求助

问题:C++调用Fortran子程序时的链接错误

环境信息

  • 系统:macOS Monterey 12.6
  • 编译器:gcc 12.1.0(含gfortran)、Apple clang 14.0.0

代码示例

Fortran代码(test_f.f90)

subroutine PRINT_NUMBER()
    use iso_c_binding 
    implicit none

    write(*,*) "This is fortran answering!"
    
end subroutine PRINT_NUMBER

C++代码(test_c.cpp)

#include <iostream>

extern "C"
{
    void print_number_();
}

int main()
{
    std::cout << "This is C++ answering!" << std::endl;
    print_number_();

    return 0;
}

遇到的错误

第一次链接错误

手动用g++链接目标文件时出现:

ld: warning: object file (test_f.o) was built for newer macOS version (12.5) than being linked (12.0)
Undefined symbols for architecture x86_64:
  "__gfortran_st_write", referenced from:
      _print_number_ in test_f.o
  "__gfortran_st_write_done", referenced from:
      _print_number_ in test_f.o
  "__gfortran_transfer_character_write", referenced from:
      _print_number_ in test_f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

手动链接libgfortran后的错误

添加-lgfortran后出现新的未定义符号:

Undefined symbols for architecture x86_64:
  "___divtf3", referenced from:
      _determine_en_precision in libgfortran.a(write.o)
      _get_float_string in libgfortran.a(write.o)
  "___eqtf2", referenced from:
      _get_float_string in libgfortran.a(write.o)
  "___gttf2", referenced from:
      _determine_en_precision in libgfortran.a(write.o)
      _get_float_string in libgfortran.a(write.o)
  "___letf2", referenced from:
      _get_float_string in libgfortran.a(write.o)
  "___lttf2", referenced from:
      _determine_en_precision in libgfortran.a(write.o)
      _get_float_string in libgfortran.a(write.o)
  "___multf3", referenced from:
      _determine_en_precision in libgfortran.a(write.o)
      _get_float_string in libgfortran.a(write.o)
  "___subtf3", referenced from:
      _determine_en_precision in libgfortran.a(write.o)
      _get_float_string in libgfortran.a(write.o)
  "___unordtf2", referenced from:
      _determine_en_precision in libgfortran.a(write.o)
      _get_float_string in libgfortran.a(write.o)
  "_quadmath_snprintf", referenced from:
      _determine_en_precision in libgfortran.a(write.o)
      _get_float_string in libgfortran.a(write.o)
  "_strtoflt128", referenced from:
      __gfortrani_convert_real in libgfortran.a(read.o)
      __gfortrani_convert_infnan in libgfortran.a(read.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

解决方案

1. 使用gfortran作为链接器(推荐)

gfortran会自动识别并链接Fortran运行时所需的所有依赖库(包括libgfortran和libquadmath),无需手动指定。执行以下命令:

  • 编译Fortran代码生成目标文件:
    gfortran -c test_f.f90 -o test_f.o
    
  • 编译C++代码生成目标文件:
    g++ -c test_c.cpp -o test_c.o
    
  • 链接生成可执行文件:
    gfortran test_c.o test_f.o -o mixed_program
    
    或者一步完成编译链接:
    g++ test_c.cpp test_f.f90 -o mixed_program -lgfortran -lquadmath
    

2. 规范名称匹配(可选但更可靠)

利用Fortran的iso_c_binding模块显式指定C兼容的子程序名称,避免默认名称修饰带来的匹配问题:
修改Fortran代码:

subroutine print_number() bind(C, name='print_number')
    use iso_c_binding 
    implicit none

    write(*,*) "This is fortran answering!"
    
end subroutine print_number

对应的C++声明改为:

extern "C"
{
    void print_number();
}

3. 消除macOS版本警告

编译时显式指定目标macOS版本,确保编译和链接的版本一致:

gfortran -c test_f.f90 -o test_f.o -mmacosx-version-min=12.6
g++ -c test_c.cpp -o test_c.o -mmacosx-version-min=12.6

内容的提问来源于stack exchange,提问作者Christ Liu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:05:06