Fortran 中动态加载动态库
文章目录一、核心原理二、完整示例Linux 平台1. 动态库源码mylib.c2. C 封装层dlwrapper.c3. Fortran 主程序main.f904. 编译与运行三、Windows 平台适配要点四、关键注意事项五、高级技巧直接使用 libdl无需 C 封装六、适用场景在 Fortran 中动态加载动态库.so或.dll需借助C 互操作性ISO_C_BINDING调用操作系统原生 API如dlopen/dlsym或LoadLibrary/GetProcAddress。Fortran 标准本身不提供动态加载接口但可通过 C 绑定桥接实现。以下分步骤说明并提供完整示例。一、核心原理步骤说明1. 编写动态库用 C 编写使用extern C避免 C 名称修饰Fortran 需通过 ISO_C_BINDING 声明接口2. 动态加载通过 C 函数封装dlopen/LoadLibraryFortran 调用该封装函数3. 获取符号通过 C 函数封装dlsym/GetProcAddress返回函数指针或变量地址4. 类型转换使用c_funptr/c_fptr在 C 函数指针与 Fortran 过程指针间转换⚠️关键点Fortran 无法直接操作void*必须通过 C 封装层中转。二、完整示例Linux 平台1. 动态库源码mylib.c// mylib.c - 编译为 libmylib.so#includestdio.h// 全局变量doubleglobal_value3.14159;// C 函数无名称修饰doublecompute(doublex,doubley){returnx*yglobal_value;}// 辅助函数返回变量地址避免 Fortran 直接处理 void*double*get_global_value_ptr(){returnglobal_value;}编译动态库gcc -shared -fPIC -o libmylib.so mylib.c2. C 封装层dlwrapper.c// dlwrapper.c - 封装 dlopen/dlsym#define_GNU_SOURCE#includedlfcn.h#includestdint.h// 返回句柄转换为 intptr_t 供 Fortran 使用intptr_topen_library(constchar*path){return(intptr_t)dlopen(path,RTLD_LAZY|RTLD_GLOBAL);}// 获取函数符号void*get_function(intptr_thandle,constchar*name){returndlsym((void*)handle,name);}// 获取变量地址void*get_variable(intptr_thandle,constchar*name){returndlsym((void*)handle,name);}// 关闭库voidclose_library(intptr_thandle){dlclose((void*)handle);}编译为静态库供 Fortran 链接gcc -c -fPIC dlwrapper.c -o dlwrapper.o ar rcs libdlwrapper.a dlwrapper.o3. Fortran 主程序main.f90program dynamic_load_example use, intrinsic :: iso_c_binding implicit none ! 接口声明 interface function open_library(path) bind(c, nameopen_library) import :: c_char, c_intptr_t character(kindc_char), intent(in) :: path(*) integer(c_intptr_t) :: open_library end function function get_function(handle, name) bind(c, nameget_function) import :: c_intptr_t, c_funptr integer(c_intptr_t), value :: handle character(kindc_char), intent(in) :: name(*) type(c_funptr) :: get_function end function function get_variable(handle, name) bind(c, nameget_variable) import :: c_intptr_t, c_ptr integer(c_intptr_t), value :: handle character(kindc_char), intent(in) :: name(*) type(c_ptr) :: get_variable end function subroutine close_library(handle) bind(c, nameclose_library) import :: c_intptr_t integer(c_intptr_t), value :: handle end subroutine end interface ! 目标函数类型声明 abstract interface function compute_func(x, y) bind(c) import :: c_double real(c_double), value :: x, y real(c_double) :: compute_func end function end interface ! 变量 integer(c_intptr_t) :: lib_handle type(c_funptr) :: func_ptr type(c_ptr) :: var_ptr procedure(compute_func), pointer :: compute_fptr null() real(c_double), pointer :: global_value_ptr null() real(c_double) :: result ! 1. 加载库 lib_handle open_library(libmylib.so // c_null_char) if (lib_handle 0) then print *, Error: Failed to load library stop end if print *, Library loaded successfully ! 2. 获取函数 func_ptr get_function(lib_handle, compute // c_null_char) if (.not. c_associated(func_ptr)) then print *, Error: Failed to get function compute call close_library(lib_handle) stop end if call c_f_procpointer(func_ptr, compute_fptr) ! 3. 获取变量 var_ptr get_variable(lib_handle, global_value // c_null_char) if (.not. c_associated(var_ptr)) then print *, Error: Failed to get variable global_value call close_library(lib_handle) stop end if call c_f_pointer(var_ptr, global_value_ptr) ! 4. 调用函数 访问变量 result compute_fptr(2.0_c_double, 3.0_c_double) print *, compute(2.0, 3.0) , result print *, global_value , global_value_ptr ! 5. 修改变量通过指针 global_value_ptr 2.71828_c_double result compute_fptr(1.0_c_double, 1.0_c_double) print *, After modification: compute(1.0,1.0) , result ! 6. 卸载库 call close_library(lib_handle) print *, Library unloaded end program dynamic_load_example4. 编译与运行# 编译 Fortran 程序链接 libdlgfortran -o main main.f90 libdlwrapper.a -ldl# 运行确保 libmylib.so 在 LD_LIBRARY_PATH 中exportLD_LIBRARY_PATH.:$LD_LIBRARY_PATH./main输出示例Library loaded successfully compute(2.0, 3.0) 9.1415900000000003 global_value 3.1415900000000001 After modification: compute(1.0,1.0) 3.7182800000000001 Library unloaded三、Windows 平台适配要点动态库编译为.dll导出函数需加__declspec(dllexport)__declspec(dllexport)doublecompute(doublex,doubley){...}封装层替换为 Windows API#includewindows.hHMODULEopen_library(constchar*path){returnLoadLibraryA(path);}FARPROCget_function(HMODULE h,constchar*name){returnGetProcAddress(h,name);}Fortran 接口将intptr_t替换为type(c_ptr)其他逻辑相同编译gfortran -o main.exe main.f90 dlwrapper.o -lkernel32四、关键注意事项问题解决方案名称修饰C 库必须用extern CC或 plain CFortran 调用时名称需与nm lib.so输出一致调用约定Linux 默认cdeclWindows 需显式指定bind(c)确保兼容指针安全使用c_associated()检查指针有效性避免解引用空指针内存管理动态库卸载后所有获取的函数/变量指针失效需在close_library前释放线程安全dlopen/LoadLibrary非线程安全多线程环境需加锁五、高级技巧直接使用 libdl无需 C 封装部分编译器如 GCC 10支持直接绑定libdl函数interface function dlopen(filename, mode) bind(c, namedlopen) import :: c_char, c_int, c_ptr character(kindc_char), intent(in) :: filename(*) integer(c_int), value :: mode type(c_ptr) :: dlopen end function end interface但需注意需链接-ldlRTLD_LAZY等常量需手动定义如integer(c_int), parameter :: RTLD_LAZY 1可移植性较差推荐使用 C 封装层六、适用场景插件化架构运行时加载算法模块避免硬编码依赖如可选的 CUDA/MPI 支持高性能计算中动态切换优化内核与 Python/C/C 生态集成如通过 ctypes 加载 Fortran 库建议生产环境推荐使用CMake 预编译封装库管理依赖避免手动处理符号和路径问题。

相关新闻

计算机毕业设计springboot校园帮助系统 基于SpringBoot的校园互助服务平台的设计与实现 面向高校的智慧校园援助系统构建——SpringBoot框架实践

计算机毕业设计springboot校园帮助系统 基于SpringBoot的校园互助服务平台的设计与实现 面向高校的智慧校园援助系统构建——SpringBoot框架实践

计算机毕业设计springboot校园帮助系统95lbi (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 当“遇事找校友”从一句口号变成随时随地的指尖动作,校园生活就被悄悄…

2026/7/4 21:49:43 阅读更多 →
计算机毕业设计springboot高校教室管理系统的设计与实现 基于SpringBoot的高校教学场地智能调度系统设计与实现 校园智慧教室资源管理与服务平台开发

计算机毕业设计springboot高校教室管理系统的设计与实现 基于SpringBoot的高校教学场地智能调度系统设计与实现 校园智慧教室资源管理与服务平台开发

计算机毕业设计springboot高校教室管理系统的设计与实现392lm110 (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 随着教育信息化进程的不断推进,高校教学资源的数字…

2026/7/3 14:41:27 阅读更多 →
远程育儿+量子开发:一位母亲的2026平衡术

远程育儿+量子开发:一位母亲的2026平衡术

在2026年的数字化浪潮中,公众号内容的热度不再依赖传统“热搜”,而是由用户需求数据驱动——点击率、停留时长和分享量成为算法推荐的核心指标。作为软件测试从业者,我们习惯于用精准的测试用例验证系统,但当育儿遇上远程工作&…

2026/7/3 14:41:30 阅读更多 →

最新新闻

终极解决方案:用ChromaControl实现所有RGB设备在雷蛇生态中的完美同步

终极解决方案:用ChromaControl实现所有RGB设备在雷蛇生态中的完美同步

终极解决方案:用ChromaControl实现所有RGB设备在雷蛇生态中的完美同步 【免费下载链接】ChromaControl 3rd party device lighting support for Razer Synapse. 项目地址: https://gitcode.com/gh_mirrors/ch/ChromaControl 还在为桌面上不同品牌的RGB设备各…

2026/7/5 0:45:59 阅读更多 →
Ceph自动化运维开发:openeuler/ceph_dev中Ansible与Terraform集成

Ceph自动化运维开发:openeuler/ceph_dev中Ansible与Terraform集成

Ceph自动化运维开发:openeuler/ceph_dev中Ansible与Terraform集成 【免费下载链接】ceph_dev ceph_dev is a project focus on some feature developing based on ceph 项目地址: https://gitcode.com/openeuler/ceph_dev 前往项目官网免费下载:h…

2026/7/5 0:43:58 阅读更多 →
【Springboot毕设全套源码+文档】基于springboot二次元商品商城系统的设计与实现(丰富项目+远程调试+讲解+定制)

【Springboot毕设全套源码+文档】基于springboot二次元商品商城系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/5 0:43:58 阅读更多 →
告别Selenium弹窗噩梦:Playwright实现无头浏览器文件自动下载实战

告别Selenium弹窗噩梦:Playwright实现无头浏览器文件自动下载实战

1. 项目概述:为什么我们要告别Selenium?如果你做过Web自动化测试或者数据抓取,尤其是涉及到文件下载的场景,那你大概率经历过“弹窗噩梦”。浏览器原生的“另存为”对话框,就像一堵无法逾越的高墙,横亘在你…

2026/7/5 0:39:55 阅读更多 →
从光学到产品:护眼钢化膜的技术原理与实现路径深度解析(以悟赫德 scinique 技术为例)

从光学到产品:护眼钢化膜的技术原理与实现路径深度解析(以悟赫德 scinique 技术为例)

1. 引言:为什么我们需要 "护眼" 的手机膜?随着 OLED 屏幕在智能手机中的全面普及,以及用户日均用屏时长的不断增加(据统计,2026 年国内用户日均手机使用时长已超过 6.5 小时),视疲劳正…

2026/7/5 0:39:55 阅读更多 →
ASM330LHH与PIC18F25K80的工业级运动跟踪系统设计

ASM330LHH与PIC18F25K80的工业级运动跟踪系统设计

1. 从传感器到系统:ASM330LHH与PIC18F25K80的硬件搭档当我在工业自动化项目中第一次接触到ASM330LHH这颗6DoF惯性测量单元(IMU)时,立刻被它的性能参数所震撼。作为意法半导体MEMS传感器家族的重要成员,它在一个3x2.5x0.83mm的封装内集成了三轴…

2026/7/5 0:35:54 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻