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_programg++ 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
相关产品推荐
相关产品推荐

