Python c_types .dll 函数(pari 库)

2 投票
1 回答
975 浏览
提问于 2025-04-15 20:55

好吧,几天前我决定尝试为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,我猜这仍然是一个地址。我正在尝试更多的命令,如果我成功获取到正确的值会更新的。

1 个回答

3

你这里有两个问题,首先是要给fibo函数设置正确的返回类型,其次是要把GEN的返回类型转换成你想要的值。

稍微查看一下源代码,你会发现GEN被定义为一个指向长整型的指针。此外,看起来这个库提供了一些转换和打印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'

撰写回答