Python ctypes .dll函数(pari库)

时间:2010-03-27 00:44:14

标签: python ctypes pari

好吧,所以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而是GEN类型,这是PARI库所独有的?任何帮助,将不胜感激。如果有人能够成功加载库并使用python中的任何函数,请告诉;我已经在这几个小时了。

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

1 个答案:

答案 0 :(得分:3)

这里有两个问题,一个给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'