Я хочу иметь возможность передавать структуру в какой-нибудь c-код и использую ctypes.structure. У меня есть простой рабочий пример, который принимает входной массив, возводит элементы в квадрат и выводит в виде массива. Однако у меня возникли проблемы с помещением этого в класс Python для создания процедуры-оболочки.
Простой код на языке C:
test. c
struct DATA;
typedef struct DATA {
int n;
double *ina;
double *outa;
} DATA;
void square_array2(DATA *data) {
int i;
for (i=0; in; i++) {
data->outa = data->ina*data->ina;
}
}
Я компилирую это с помощью
gcc -shared -fPIC test.c -o test.so
В блокноте Jupyter у меня есть:
import importlib
import numpy as np
import ctypes
from ctypes import CDLL, POINTER
from ctypes import c_size_t, c_double
from wurlitzer import pipes, STDOUT
%reload_ext wurlitzer
testlib = CDLL('test.so')
n=5
ina = np.linspace(1.0,5.0,n)
outa = np.zeros(n,np.float64)
class Data(ctypes.Structure):
_fields_ = [("n", ctypes.c_int),
("ina", ctypes.POINTER(ctypes.c_double)),
("outa", ctypes.POINTER(ctypes.c_double))]
data = Data(n,np.ctypeslib.as_ctypes(ina),np.ctypeslib.as_ctypes(outa))
print("initial array",ina)
testlib.square_array2.restype = None
testlib.square_array2(ctypes.byref(data))
print("final array",outa)
Все это прекрасно работает из блокнота Jupyter.
Часть, которая не работает, — это помещение
в класс Python обертка.
Вот моя попытка создания оболочки, которая не сработала:
import ctypes
from ctypes import CDLL, POINTER
from ctypes import c_size_t, c_double, c_int
from io import StringIO
from wurlitzer import pipes, STDOUT
class Data(ctypes.Structure):
_fields_ = [("n", ctypes.c_int),
("ina", ctypes.POINTER(ctypes.c_double)),
("outa", ctypes.POINTER(ctypes.c_double))]
class testClib(Data): #attempting to inherit the Data class.
def __init__(self):
# load the library
self.lib = CDLL("test.so")
def square_array2(self,ina,outa):
n, = ina.shape
# !!! the line that doesn't work....
data = Data(n,np.ctypeslib.as_ctypes(ina),np.ctypeslib.as_ctypes(outa))
out = StringIO()
with pipes(stdout=out, stderr=STDOUT):
self.lib.square_array2.restype = None
self.lib.square_array2(ctypes.byref(data))
stdout = out.getvalue()
print(stdout)
print(ina)
print(outa)
Я вызываю эту процедуру из своего блокнота Jupyter с помощью команды:
ctest.square_array2(ina,outa)
Сообщение об ошибке при выполнении:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[51], line 3
1 # lets add this in a wrapper routine
----> 3 ctest.square_array2(ina,outa)
File ~/WORK/PYTHONLIB/ctypesTEST/ctypesTEST3.py:46, in testClib.square_array2(self, ina, outa)
42 def square_array2(self,ina,outa):
44 n, = ina.shape
---> 46 data = Data(n,np.ctypeslib.as_ctypes(ina),np.ctypeslib.as_ctypes(outa))
48 out = StringIO()
50 with pipes(stdout=out, stderr=STDOUT):
TypeError: too many initializers
Подробнее здесь: https://stackoverflow.com/questions/791 ... de-a-class
Упаковка ctypes. Структура внутри класса ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение