使用 ctypes 将 python 字符串传递给 Fortran 子例程

2024-01-21

我正在尝试使用 ctypes 将参数传递给共享库中的 Fortran 子例程。现在这是我的简单 fortran 代码:

MODULE test_module
INCLUDES
SUBROUTINE fstr_test(file_or_extension, ierr, iopen)
   IMPLICIT NONE
   INTEGER, INTENT(out) :: ierr
   INTEGER, OPTIONAL :: iopen
   CHARACTER(LEN=*), INTENT(in) :: file_or_extension
   WRITE(6,*) file_or_extension,ierr,iopen
   RETURN
END SUBROUTINE fstr_test
END MODULE test_module

我编译这个

gcc -shared -fPIC -o libtest.o fstr_test.f90

这似乎工作正常,事实上我可以在 Python 3 中加载共享库。这是非崩溃代码:

from ctypes import *
libtest = cdll.LoadLibrary("libtest.so")
f = libtest.test_module_MOD__fstr_test
file = b'wout_li383.nc'
ierr = c_int(0)
iopen = c_int(0)
cfile=c_char_p(b"test_str")
f(cfile,byref(ierr),byref(iopen))

但是,我似乎无法正确传递字符串。在上面的形式中,字符串为空,两个整数正确打印到控制台。基本上我取得的唯一进展就是让 Python 崩溃。我在这里尝试了解决方案:

使用 ctypes 和 Python 将字符串传递给 Fortran DLL https://stackoverflow.com/questions/23641754/passing-string-to-fortran-dll-using-ctypes-and-python

但它似乎对我不起作用,也许是因为它谈论的是Python 2?

例如

f.argtype = [c_char_p,c_int_c_int]
c = c_char_p(b"test.txt")
f(c,byref(ierr),byref(iopen))

不会使内核崩溃,但字符串为空。更改为 byref:

f.argtype = [c_char_p,c_int_c_int]
c = c_char_p(b"test.txt")
f(byref(c),byref(ierr),byref(iopen))

效果相同。现在,如果我尝试通过添加长度参数并传递它来传递长度,我会收到一条“死内核”消息,并且我必须重新启动内核。本身没有错误消息。

f.argtype = [c_char_p,c_int,c_int_c_int]
file = b'text.txt'
c = c_char_p(file)
c_len = c_int(len(file))
f(c,byref(c_len),byref(ierr),byref(iopen))

希望这能澄清。我没有收到错误消息,内核快要死了。


所以有几个问题,其中之一是隐藏长度(至少 gfortran 不知道其他编译器做什么)应该放在参数列表的末尾。您也不需要 byref,也不会将字节字符串包装在 c_char_p 中

更改子例程中的 irr 变量

  SUBROUTINE fstr_test(file_or_extension, ierr, iopen)
     IMPLICIT NONE
     INTEGER, INTENT(out) :: ierr
     INTEGER, OPTIONAL :: iopen
     CHARACTER(LEN=*), INTENT(in) :: file_or_extension
     WRITE(6,*) file_or_extension,ierr,iopen
     ierr=1
     RETURN
  END SUBROUTINE fstr_test

and

gfortran -shared -fPIC -o libtest.so fstr_test.f90

那么python代码应该是这样的:

import ctypes

lib=ctypes.CDLL("./libtest.so")
f=getattr(lib,'__test_module_MOD_fstr_test')

f.argtypes=[ctypes.c_char_p,ctypes.c_int,ctypes.c_int,ctypes.c_int]
f.restype=None

x=b'abcdef'
ierr=ctypes.c_int(0)
iopen=0
f(x,ctypes.byref(ierr),iopen,len(x))
print(ierr.value)

虽然我还没有让可选参数起作用,所以我添加了一个空 int,但这应该是你将字符串传入并得到 ierr 的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ctypes 将 python 字符串传递给 Fortran 子例程 的相关文章

  • ptb_word_lm中batch_size的含义(tensorflow的LSTM模型)

    我是张量流的新手 我现在对它的含义有点困惑batch size 众所周知 其含义是batch size是每批次的样本数 但是根据中的代码ptb word lm 似乎不是 读者 py data len tf size raw data the
  • 在Python中用空格分割字符串——保留带引号的子字符串

    我有一个像这样的字符串 this is a test 我正在尝试用 Python 编写一些内容 以将其按空格分开 同时忽略引号内的空格 我正在寻找的结果是 this is a test 附言 我知道您会问 如果引号内有引号会发生什么 嗯 在
  • 检查字符串是否以 XXXX 开头

    我想知道如何在Python中检查字符串是否以 hello 开头 在 Bash 中我通常这样做 if string hello then do something here fi 我如何在Python中实现同样的效果 aString hell
  • 如何在python包中包含.pyx文件

    我在我的包中使用了 cythonpyirt https github com 17zuoye pyirt 但是当我将其发布到 pypi 时 pyx 文件不包含在 tar gz 中 我认为这一定与安装文件有关 但是 我找不到解决这个问题的方法
  • PySerial 和多个 Python 安装出现问题

    我的 Windows 7 计算机上有 Python 2 4 4 和 3 1 3 我想使用 PySerial 听说是内置的 所以我尝试了一下import serial在两个版本中 两者都造成了Import Error 然后我从以下位置下载了w
  • 如何让MagicMock返回多个值

    我想模拟一个图书馆 matplotlib对于它的价值 并且遇到一个问题 当调用模拟并期望返回元组时 它会失败 有一个更好的方法吗 Python 3 7 2 default Jan 13 2019 12 50 15 Clang 10 0 0
  • 如何使用 Tkinter 创建等宽网格列?

    如何强制 Tkinter 应用程序窗口中的列宽度相等 tkdocs网站声明如下 每列的宽度 或每行的高度 取决于列或行中包含的小部件的宽度或高度 这意味着当绘制用户界面并将其划分为行和列时 您无需担心每列或行的宽度相等 或高度 大概 TkD
  • 继承类中的python __init__方法[重复]

    这个问题在这里已经有答案了 我想为子类提供一些额外的属性 而不必显式调用新方法 那么有没有办法给继承的类一个 init 不重写的类型方法 init 父类的方法 我编写下面的代码纯粹是为了说明我的问题 因此属性等的命名很糟糕 class in
  • 您能否从函数、args 和 kwargs 确定变量将如何分配?

    我有一些样板逻辑 我想包装几个具有相同可选关键字的函数 现在看起来像下面的代码 但是 这仅处理 opt key 作为关键字传递的情况 而不是按位置传递 解决这个问题的一种方法是了解如何解决参数分配 是否有一些元函数接受函数 args 和 k
  • 如何使用 Python Flask-Security 使用 bcrypt 加密密码?

    我正在尝试使用 Flask Security 文档中的标准基本示例 并使其正常工作 除了密码以明文形式存储之外 我知道这一行 user datastore create user email email protected cdn cgi
  • Django:上传前调整图像大小

    我想调整图像大小 Pillow 在上传之前 我在下面编写了代码但不起作用 并得到错误 myapp list 处的属性错误 坚定的 请求方式 POST 请求网址 http 127 0 0 1 8000 myapp list http 127
  • 仅打印字符串中的元音

    我是Python新手 我正在尝试打印字符串中的所有元音 因此 如果有人输入 嘿 一切都好吗 所有元音都需要打印 但我不知道怎么做 所以这不是计算元音 而是打印元音 现在我已经得到了这个 sentence input Enter your s
  • Django 1.6:如何在视图中访问静态文件

    我已经尝试过解决方案here https stackoverflow com questions 11721818 django get the static files url in view这对我不起作用 我正在为 Python 创建一
  • Python 中的“finally”总是执行吗?

    对于Python中任何可能的try finally块 是否保证finally块总是会被执行吗 例如 假设我在except block try 1 0 except ZeroDivisionError return finally print
  • 如何使用 Python 3 在 OpenCV 3 上正确加载 cv2.KeyPoint 和描述符?

    有一天 我不得不恢复一个使用 OpenCV 3 和 Python 2 7 的旧项目 在此代码中 要加载 cv2 KeyPoint 我执行以下操作 import numpy as np import cPickle import cv2 ke
  • 纯Python库读写jpeg格式

    伙计们 我正在寻找 jpeg 写入 阅读会很好 但不是必需的 库的纯 python 实现 我只在以下位置创建了 TonyJPEG 库端口 http mail python org pipermail image sig 2004 Novem
  • 通过 Tweepy 在 Twitter 上更新状态时的回溯

    我一直在尝试使用 Twitter 在 Twitter 上发布我的 Rpi 读数tweepy 但首先我想检查一下是否tweepy本来可以正常工作 但事实并非如此 我正确安装了软件包 但是当我尝试运行简单的代码来发布某些内容时 出现错误 是的
  • vtkPythonAlgorithm 控制管道执行

    我正在尝试用 python 编写一个 vtk 过滤器ProjectDepthImage进行投影不是问题 它控制 vtk 管道的执行 基本上 我对 UserEvent 有一个回调 当用户在渲染窗口处于活动状态时按下 u 键时会触发该回调 这将
  • 媒体文件上的 404 - Django

    昨晚我将项目上传到 pythonanywhere com 我想在那里测试我的项目生产设置 在我允许的模型之一中用户上传JPG 团队徽标 上传过程运行良好 文件位于我的 MEDIA ROOT 中 问题是 当我尝试在模板中访问它 以将其显示在页
  • 每次 apache 重新启动时,flask-login 会话都会被破坏

    我正在使用烧瓶登录https github com maxcountryman flask login https github com maxcountryman flask login和领域记住登录用户 http packages py

随机推荐