【问题标题】:Python c_types .dll functions (pari library)Python c_types .dll 函数(pari 库)
【发布时间】:2010-03-27 00:44:14
【问题描述】:

好的,所以a couple days ago 我决定尝试为 PARI 库编写一个原始包装器。从那时起,我一直在使用ctypes 库来加载 dll 并使用类似于以下的代码访问包含的函数:

from ctypes import *
libcyg=CDLL("<path/cygwin1.dll") #It needs cygwin to be loaded. Not sure why.
pari=CDLL("<path>/libpari-gmp-2.4.dll")

print pari.fibo #fibonacci function
#prints something like "<_FuncPtr object at 0x00BA5828>"

所以功能在那里并且可能被访问,但无论我尝试什么,我总是收到访问冲突。例如:

pari.fibo(5) #access violation
pari.fibo(c_int(5)) #access violation

pari.fibo.argtypes = [c_long] #setting arguments manually
pari.fibo.restype = long #set the return type

pari.fibo(byref(c_int(5))) #access violation reading 0x04 consistently

以及任何变化,包括设置argtypes 来接收指针。

Pari .dll 是用 C 语言编写的,库中斐波那契函数的语法是 GEN fibo(long x)

可能是导致这些错误的返回类型,因为它不是标准的 intlong,而是 PARI 库独有的 GEN 类型?任何帮助,将不胜感激。如果有人能够成功加载库并使用 python 中的任何函数,请告诉;我已经在这里工作了好几个小时了。

编辑:好像我只是忘记初始化库。在快速pari.pari_init(4000000,500000) 之后,它停止了错误。现在我的问题在于它返回一个 GEN 对象;这很好,但是每当我尝试引用它指向的地址时,它总是 33554435,我认为它仍然是一个地址。我正在尝试进一步的命令,如果我成功获得某些东西的正确值,我会更新。

【问题讨论】:

  • 我认为 GEN 可能是一个问题,因为它显然是“指向 long 的指针”。但是返回一个指针需要指向的东西,在这种情况下,我不知道它是什么或谁分配了它。其他想法是这与 cygwin 有关,或者您使用的是 64 位机器,而这里的某些东西需要 32 位。
  • 在我的机器上(Windows 7、32 位、Python 2.6.5)我什至无法加载 libpari DLL。我的会话锁定在 CDLL() 调用上。基于 cygwin 的包不是必须在 cygwin 会话中运行吗?我当然没有使用 Python 的 cygwin 构建...
  • 我在 32 位 Windows XP SP2 上运行 Python 2.6.2,尽管它在 2.6.4 和 2.5.1 中都加载。我的朋友在加载 libpari 时遇到了确切的问题;他在调试模式下运行他的代码并成功加载。
  • @silinter:再次修复了第二个链接。也赞成你的两个问题。我忘记了添加 >1 链接需要多少代表,但也许这会有所帮助。 :) (也在这里的 Win XP 机器上尝试过同样的事情,但它仍然为我锁定。抱歉,我不能提供更多帮助。)
  • 谢谢。我会继续努力;我想我只是缺少一些 ctypes 命令来正确地将参数传递/接收到 .dll 的。我将正确阅读 PARI lib 的文档,并在我了解更多 PARI 正在做什么时继续。

标签: python ctypes pari


【解决方案1】:

这里有两个问题,一是给 fibo 正确的返回类型,二是把 GEN 返回类型转换为您要查找的值。

浏览一下源代码,您会发现 GEN 被定义为指向 long 的指针。此外,看起来该库提供了一些转换/打印 GEN。我专注于 GENtostr,因为它对所有 pari 函数可能更安全。

import cytpes
pari = ctypes.CDLL("./libpari.so.2.3.5") #I did this under linux
pari.fibo.restype = ctypes.POINTER(ctypes.c_long)
pari.GENtostr.restype = ctypes.POINTER(ctypes.c_char)    
pari.pari_init(4000000,500000)
x = pari.fibo(100)
y = pari.GENtostr(x)
ctypes.string_at(y)

结果:

'354224848179261915075'

【讨论】:

  • 哇,这绝对是完美的。我最终确实发现我需要将返回类型设置为 POINTER,但我想我不知道 ctypes(或 paric lib :( )足以正确接收结果;它一直返回一个指针,当我取消引用它时,我总是必须在它指向的地址之后检查大约 8 个字节的内存地址。非常感谢。此外,您是否碰巧知道相关 ctypes 调用的任何好的参考?或者一般教程/ctypes 参考有什么作用?
  • @silinter,标准的 ctypes 文档非常详尽,docs.python.org/library/ctypes.html。 SciPy 文档还谈到了将它与 Numpy 一起使用,可能就在你的小巷里:scipy.org/Cookbook/Ctypes
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-06
  • 2013-01-25
  • 2021-10-05
  • 2023-04-09
  • 1970-01-01
  • 2013-12-19
相关资源
最近更新 更多