- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
经历:
fortran大约3个月
python - 中级:在此之前从未在 python 中使用过 ctypes 模块
我一直在寻找一种方法来使用 fortran 代码来完成我在 python 方面的博士工作——随后使用 matplotlib 进行可视化的动态计算。
THIS POST帮助(这表明可以使用 ctypes 模块在 python 中使用/调用 fortran 代码 - 并且考虑到 fortran 函数具有绑定(bind)到它们的备用名称 - 这在逻辑上对我来说很有意义,尽管我不知道它是如何工作的细节。但我们确实明智地选择了我们的战斗!)。
那么this SO post也处理从 python 调用 fortran 函数。
下一个合乎逻辑的步骤是查找 documentation for the python module ctypes .这讨论了如何在 API 级别使用 python 访问共享库。
我有所有的东西来制作一个最小的工作示例,another answer has already done .但我想看看涉及真实 float 的输出机制和数学运算。这是我做的测试用例。
function prnt(s)
character(80):: s
logical :: prnt
print*, s
prnt = .true.
end function prnt
function sin_2(r)
real:: r,sin_2
sin_2 = sin(r)**2
end function sin_2
$gfortran -shared -g -o test.so test.f90
编辑:出于某种原因,我的工作计算机需要 -fPIC 选项才能编译
为了确保我的两个函数 prnt
和 sin_2
在某处,我检查了 nm
:
$ nm test.so | tail -3
0000067f T prnt_
0000065c T sin_2_
U sinf@@GLIBC_2.0
到目前为止一切顺利。我的函数 prnt
和 sin_2
已经映射到库中的 prnt_
和 sin_2_
上。
这就是所有这一切变得有点湿透的地方。使用the table in python-ctypes documentation ,我输入了以下内容 -
>>> from ctypes import byref, cdll, c_float,c_char_p
>>> t = cdll.LoadLibrary('./test.so')
>>> c = c_char_p("Mary had a little lamb")
>>> t.prnt_('Mary had a little lamb')
Mary had a little lambe
1
>>> t.prnt_("Mary had a little lamb")
Mary had a little lambe
1
>>> t.prnt_(c)
Mary had a little lambe[� .prnt_(c)
1
我想每个输出末尾打印的 1 是 python 让我知道 t.prnt_
的 bool 输出是 .true.
的方式。< br/>当我切换到字符串的正确数据类型时,我有点担心 t.prnt_
的情况会变得更糟。文字打印没问题,只是结尾有一个 e
。那是 EOL 角色吗?
然后是t.sin_2_
函数。我决定用它来计算 sin(4.56)**2。这是怎么回事-
>>> f = c_float(4.56)
>>> t.sin_2_(4.56)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1
>>> t.sin_2_(f)
Segmentation fault (core dumped)
我哪里错了?我试图解释我是如何处理这个问题的,这样如果我在某个地方犯了明显的错误,就会很明显。
指向其他 SO 帖子的大量链接是为了帮助其他和我现在问同样问题的人。
最佳答案
在 Fortran 中,参数通过引用传递。 Fortran 字符数组不是空终止的;长度作为隐式 long int
参数按值传递。此外,Python 的 float
类型是 double
,因此您可能希望使用 Fortran real(8)
来保持一致性。
测试.f90:
function prnt(s) ! byref(s), byval(length) [long int, implicit]
character(len=*):: s ! variable length input
logical :: prnt
write(*, "(A)") s ! formatted, to remove initial space
prnt = .true.
end function prnt
function sin_2(r) ! byref(r)
real:: r, sin_2 ! float; use real(8) for double
sin_2 = sin(r)**2
end function sin_2
请记住为函数设置 ctypes argtypes
,并在适当的地方设置 restype
。在这种情况下,sin_2
接受一个浮点指针并返回一个 float 。
ctypes 示例:
>>> from ctypes import *
>>> test = CDLL('./test.so')
>>> test.prnt_.argtypes = [c_char_p, c_long]
>>> test.sin_2_.argtypes = [POINTER(c_float)]
>>> test.sin_2_.restype = c_float
>>> s = 'Mary had a little lamb'
>>> test.prnt_(s, len(s))
Mary had a little lamb
1
>>> x = c_float(4.56)
>>> test.sin_2_(byref(x))
0.9769567847251892
关于python - 使用 python-ctypes 将 fortran 与 python 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15875533/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!