将 C 字符串数组传递给 Fortran (iso_c_binding)

2024-04-18

如何传递 C 字符串数组(char* cstrings[]) 到 Fortran 子程序?

问题使用 iso_c_binding 的 fortran-C 桥接器中的字符串数组 https://stackoverflow.com/questions/9686532肯定是相关的,但答案似乎不正确,甚至不能用 GNU Fortran 编译。

我目前正在为 Fortran 代码开发 C 接口,我期望iso_c_binding(我以前用过)会让这变得小菜一碟。到目前为止,C 字符串数组还没有运气......

Fortran 子例程应采用字符串数组作为参数。 在普通的 Fortran 语言中,我会写如下内容:

subroutine print_fstring_array(fstring)

  implicit none

  character(len=*), dimension(:), intent(in) :: fstring
  integer                                    :: i

  do i = 1, size(fstring)
    write(*,*) trim(fstring(i))
  end do

end subroutine print_fstring_array

将单个 C 字符串传递给 Fortran 的一种方法是作为 C 指针 (c_ptr)(我知道,我也可以使用一系列character(kind=c_char))

subroutine print_cstring(cstring) bind(C)

  use iso_c_binding, only: c_ptr, c_f_pointer, c_loc, c_null_char
  implicit none

  type(c_ptr), target, intent(in) :: cstring
  character(len=1024), pointer    :: fstring
  integer                         :: slen

  call c_f_pointer(c_loc(cstring), fstring)
  slen = index(fstring, c_null_char) - 1
  write(*,*) fstring(1:slen)

end subroutine print_cstring

所以,我假设了一个数组c_ptr是个好主意

subroutine print_cstring_array(n, cstring) bind(C)

  use iso_c_binding, only: c_ptr, c_int, c_f_pointer, c_loc, c_null_char
  implicit none

  integer(kind=c_int),               intent(in) :: n
  type(c_ptr), dimension(n), target, intent(in) :: cstring
  character(len=1024), pointer                  :: fstr
  integer                                       :: slen, i

  do i = 1, n
    call c_f_pointer(c_loc(cstring(i)), fstring)
    slen = index(fstring, c_null_char) - 1
    write(*,*) fstring(1:slen)
  end do

end subroutine print_cstring_array

但这会产生分段错误。

最后一个示例的 C 代码是

# include "stdio.h"
# include "fstring.h"

void main(void) {
  char* cstring[] = { "abc", "def", "ghi", "jkl" };
  int n = 4;
  print_cstring_array(&n, cstring);
}

以及头文件的内容fstring.h很简单:

void print_cstring_array(int* n, char* cstring[]);

我的目标是 GNU Fortran 和 Intel Fortran,并已使用 GNU Fortran 测试了上述内容。这字符串的长度是固定的(上例中的 3),以防这简化了解决方案。然而,数组的维度可以变化。

任何指针(甚至 C 指针)都将不胜感激。


问题中代码中最大的问题是您使用c_f_pointer(c_loc(cstring),代替c_f_pointer(cstring,.

这对我有用:

subroutine print_cstring_array(n, cstring) bind(C)

  use iso_c_binding, only: c_ptr, c_int, c_f_pointer, c_loc, c_null_char
  implicit none

  integer(kind=c_int),               intent(in) :: n
  type(c_ptr), dimension(n), target, intent(in) :: cstring
  character, pointer                            :: fstring(:)
  integer                                       :: slen, i

  do i = 1, n
    call c_f_pointer(cstring(i), fstring, [4])
    write(*,*) fstring
  end do

end subroutine print_cstring_array



# include "stdio.h"

void print_cstring_array(int* n, char* cstring[]);

void main(void) {
  char* cstring[] = { "abc", "def", "ghi", "jkl" };
  int n = 4;
  print_cstring_array(&n, cstring);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 C 字符串数组传递给 Fortran (iso_c_binding) 的相关文章

随机推荐

  • AspectJ 是如何工作的?

    我正在尝试了解 Aspect 的工作原理 我有 C C 背景 但魔法永远不会发生 我知道你可以用注释一些函数 Aspect然后写下Aspect的实现等等 但是 新代码是如何 以及在 什么时间 生成的 假设我没有编辑器 我使用编译java类j
  • elasticsearch中@timestamp和timestamp字段的区别

    当我使用日志存储向弹性搜索记录一些请求时 它将 timestamp 字段作为时间 当我使用 NEST 记录这些请求并设置时间戳字段时 它会放置时间戳字段 当我使用 kibana 查看数据时 这两个字段具有单独的名称 他们之间有什么区别 ti
  • 使用“-prune”时,从“find”命令中省略“-print”

    我一直无法完全理解 find 命令的 prune 操作 但实际上 至少我的一些误解源于省略 print 表达的影响 从 查找 手册页 如果表达式除 prune 之外不包含任何操作 则对表达式为 true 的所有文件执行 print 我一直
  • 使用 Tkinter 将鼠标悬停在文本上时更改文本颜色?

    所以我在 Tkinter 的画布上有一堆文本 我想让它在鼠标悬停在文本上时文本颜色发生变化 对于我的生活 我不知道如何做到这一点 并且似乎没有很多关于 Tkinter 的信息 for city in Cities CityText Citi
  • 优化康威的“生命游戏”

    为了进行实验 我 很久以前 实施了康威的生命游戏 http en wikipedia org wiki Conway s Game of Life 而且我知道this https stackoverflow com questions 18
  • Tkinter 主窗口焦点

    我有以下代码 window Tk window lift window attributes topmost True 这段代码的工作原理是将我的 Tkinter 窗口显示在所有其他窗口之上 但它仍然只解决了一半的问题 虽然该窗口实际上显示
  • 将 lambda 函数应用于 dask 数据框

    我正在寻找申请lambda如果列中的标签小于一定百分比 则使用 dask 数据框的函数来更改列中的标签 我使用的方法适用于 pandas 数据框 但相同的代码不适用于 dask 数据框 代码如下 df pd DataFrame A ant
  • 将多个单元格添加到单行

    我对此很陌生 当我尝试将多个单元格添加到一行时 它说有不可读的内容 这是我所拥有的 SpreadsheetDocument ssDoc SpreadsheetDocument Create saveFile SpreadsheetDocum
  • 作为单独用户运行应用程序的最佳初始化脚本

    我有一个在用户帐户 基于 Plack 中运行的应用程序 并且需要一个初始化脚本 它看起来就像 sudo user start server 一样简单 我刚刚使用 start stop daemon 编写了一个 LSB 脚本 它确实很笨拙且冗
  • Apple HLS 中的 PES 数据包内的访问单元如何对齐?

    Apple 是否指定了这一点 PES 数据包有效负载中应放置多少个访问单元 另外 我想知道 PES 数据包中存在哪些前缀起始代码 如果有 我认为访问单元中第一个 NAL 单元之前的单元是无用的 不能放置 正确的 我想知道它是如何在 HLS
  • 使用 PHPUnit 和 Selenium 设置测试

    您能帮我设置测试环境吗 我在 Ubuntu 上运行 安装了 并运行 selenium Web 服务器 并通过 PHPUnit 执行我的测试 最有可能的是我陷入了一些小错误 但我现在不知道如何修复它 我的代码很简单 class WebTest
  • WPF Square 自动调整父容器大小

    我有一个UniformGrid我的 WPF 项目中的对象有 2 行和 3 列 其宽度和高度设置为自动 两种对齐方式都设置为拉伸 该网格将容纳 6squares我想尽可能多地填充他们的单元格 并水平和垂直居中 我需要添加什么才能允许方块根据父
  • 如何在localStorage中存储数组?

    我有一个数据属性 data return playWord baseWord result 并回应 baseWord Amazing 每次我在 api 中发送新请求时 基本词都会发生变化 我想将每个数据存储在本地存储中并将字符串值发送到 a
  • 具有区域格式的 NSDateFormatter

    我使用此代码来处理来自 json feed 的日期字符串 NSDateFormatter formatter NSDateFormatter alloc init formatter setDateStyle NSDateFormatter
  • 如何让 gif 动画在 WPF 中工作?

    我应该使用什么控制类型 Image MediaElement etc 我无法得到这个问题的最流行的答案 上面由达里奥 正常工作 结果是奇怪的 断断续续的动画和奇怪的伪影 到目前为止我找到的最佳解决方案 https github com Xa
  • Hibernate:是否可以在二级缓存中保存瞬态字段?

    我需要跟踪持久实体的字段 该字段会经常更改 并且实际上并不是该实体的功能 而是某种计算 有时 用户希望查看该计算结果 但这种情况非常罕见 每月一次左右 因此 必须以某种方式保存此计算的结果 但我想避免每次更改时都将其保存在数据库中 因为这每
  • “找不到类‘android.support.v4.app.FragmentActivity’”错误

    我收到以下错误 gt 02 06 23 10 24 104 E dalvikvm 912 Could not find class gt android support v4 app FragmentActivity referenced
  • 如何使用SVM求精确率、召回率、准确率?

    重复计算 Precision Recall 和 F Score https stackoverflow com questions 16927964 how to calculate precision recall and f score
  • 在 Yii 的视图中我应该更喜欢使用 widget 还是 renderPartial?

    当我应该在视图文件中使用自定义小部件或 renderPartial 时 我很困惑 有时我使用 widget 有时我使用 renderPartial Widget You use widget当您的应用程序逻辑定义在单独的类文件并且逻辑在某种
  • 将 C 字符串数组传递给 Fortran (iso_c_binding)

    如何传递 C 字符串数组 char cstrings 到 Fortran 子程序 问题使用 iso c binding 的 fortran C 桥接器中的字符串数组 https stackoverflow com questions 968