Python c_types .dll функции (библиотека Pari) - PullRequest
2 голосов
/ 27 марта 2010

Хорошо, поэтому пару дней назад Я решил попробовать написать примитивную оболочку для библиотеки 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).

Может ли это быть типом возврата, который вызывает эти ошибки, поскольку это не стандартный int или long, а тип GEN, который уникален для библиотеки PARI? Любая помощь будет оценена. Если кто-то может успешно загрузить библиотеку и использовать ЛЮБУЮ функцию из Python, пожалуйста, сообщите; Я занимаюсь этим часами.

РЕДАКТИРОВАТЬ: Кажется, я просто забыл инициализировать библиотеку. После быстрого pari.pari_init(4000000,500000) он перестал ошибаться. Теперь моя проблема заключается в том, что он возвращает объект GEN; это нормально, но всякий раз, когда я пытаюсь сослаться на адрес, на который он указывает, это всегда 33554435, который, я полагаю, все еще является адресом. Я пробую дальнейшие команды, и я обновлю, если мне удастся получить правильное значение чего-либо.

1 Ответ

3 голосов
/ 27 марта 2010

У вас есть две проблемы: одна дает fibo правильный тип возвращаемого значения, а две преобразуют тип возвращаемого значения GEN в искомое значение.

Немного покопавшись в исходном коде, вы обнаружите, что GEN определен как указатель на long. Кроме того, похоже, что библиотека предоставляет некоторые конвертирующие / печатающие GEN. Я сосредоточился на GENtostr, так как он, вероятно, будет безопаснее для всех пари функций.

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'
...