Fortran Coder

查看: 1024|回复: 2
打印 上一主题 下一主题

[混编] F2018标准C descriptors初体验

[复制链接]

156

帖子

45

主题

1

精华

宗师

F 币
1368 元
贡献
649 点
跳转到指定楼层
楼主
发表于 2024-6-26 02:14:47 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 weixing1531 于 2024-6-30 17:56 编辑

F2018标准进一步加强了与C语言交互,搞出来C descriptors这个新玩意,主要以结构体CFI_cdesc_t为载体用于C语言操作Fortran中动态数组、数组切片,指针、递延字符串、访问派生类型成员变量、访问二维数组元素、optional、TYPE(*)、DIMENSION(..)等高级特性。

以下是C descritors操作递延字符串的一个例子,使用C语言strtok函数模拟Fortran2023标准子程序split来分裂字符串。
系统环境:Windows10
编译器:SimplyFortran3.35+gnu14.1.0
C语言代码:
[C] 纯文本查看 复制代码
01#include<stdlib.h>
02#include "iso_fortran_binding.h"
03#include<stdio.h>
04#include<string.h>
05//*str:被搜索字符串 *ft:间隔符集合 *num:分裂个数 ans:C descriptors
06void c_split(char *str,const char *ft,int *num,CFI_cdesc_t *ans){
07    char *token=NULL;
08    char out[255]; //提取的字符串 char *out; 会报错
09    size_t width,len=0; //字符串总长度
10     
11    *num=0; //分裂个数
12    token=strtok(str,ft); //C函数
13    printf("++++++C函数内部计算过程开始++++++\n");
14 
15    while(token!=NULL){
16        width=strlen(token); //每个子字符串长度
17        strncpy(out+len,token,width); //out为字符串首地址
18        strncpy(out+len+width,",",1); //逗号间隔
19        len=len+width+1; //包含,的长度
20        printf("[%d]:%s\n",*num,token); //打印中间成果
21        *num=*num+1; //分裂个数
22        token=strtok(NULL,ft); //C函数
23    }
24    len=len-1; //字符串长度
25    strncpy(out+len,"\0",1); //将尾部,改为\0
26    printf("++++++C函数内部计算过程结束++++++\n");
27     
28    if (ans->base_addr) { //已分配内存
29        if (CFI_deallocate(ans)) return; //非0释放内存失败
30    }
31 
32    if (out) {
33        if (CFI_allocate(ans,(CFI_index_t*)0,(CFI_index_t*)0,len)) return; //非0分配内存失败
34        memcpy(ans->base_addr,out,len); //字符串内存拷贝
35    }
36}


Fortran代码:
[Fortran] 纯文本查看 复制代码
01program main
02    use iso_c_binding
03    implicit none
04 
05    interface
06        !void c_split(char *str,const char *ft,int *num,CFI_cdesc_t *ans)
07        subroutine c_split(str,ft,num,ans) bind(c) !封装c语言strtok子程序
08            import::c_char,c_int
09            character(c_char),intent(in)::str(*),ft(*)
10            integer(c_int)::num !分裂个数
11            character(:,c_char), allocatable, intent(out) :: ans !递延字符串
12        end subroutine
13    end interface
14 
15    integer(c_int)::r,g,b,num
16    character(255)::temp_str !用于字符串占位
17    character(:),allocatable::str,sep !被解析字符串 间隔符
18    character(:,c_char),allocatable::ans !递延字符串
19 
20    str="SetColor(255,30,58)" !被解析字符串
21    write(*,"('原始字符串:',a)")str
22    sep=str(13:13) !间隔符,
23    !分隔符集合"(,)"
24    call c_split(str//c_null_char,"("//sep//")"//c_null_char,num,ans)
25     
26    write(*,"('分裂个数:',i0)")num
27    write(*,"('提取字符串长度:',i0)")len(ans)
28    write(*,"('提取字符串长度(验算):',i0)")storage_size(ans)/storage_size(ans(1:1))
29    write(*,"('提取的字符串:',a)") ans !提取的字符串
30    read(ans,*)temp_str,r,g,b
31    write(*,"('rgb的数值分别为:',*(g0,:,','))")r,g,b
32 
33    deallocate(ans,str,sep)
34    read(*,*)
35end program










分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

156

帖子

45

主题

1

精华

宗师

F 币
1368 元
贡献
649 点
板凳
 楼主| 发表于 2024-6-26 10:57:24 | 只看该作者
本帖最后由 weixing1531 于 2024-6-26 11:18 编辑
fcode 发表于 2024-6-26 10:04
嚯,反向适配了这是。
以前 ISO_C_Binding 还是在 Fortran 领空内适配(迁就)C语言。
现在牛气了,干预到  ...

len(ans)报错
可能gfortran支持还不够好
Fortran傍上C这个大款后,准备抢班夺权了。

2038

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1676 元
贡献
715 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2024-6-26 10:04:56 | 只看该作者
嚯,反向适配了这是。
以前 ISO_C_Binding 还是在 Fortran 领空内适配(迁就)C语言。
现在牛气了,干预到 C 语言领空去了。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2025-5-3 22:38

Powered by Discuz! X3.4

© 2013-2025 Comsenz Inc.

快速回复 返回顶部 返回列表