Мне нужно передать указатель из Python в функцию C. Я сейчас пытаюсь с SWIG, но я готов переключиться на все, что решит мою проблему :)
Чтобы упростить мою проблему, я написал эту пустую функцию C в SWIG:
extern void myvoidp(void *p);
Я setup мои.i и.c архивы, все компилируют отлично и работают в Python.
Я хотел бы передать массив Numpy. Я могу получить адрес памяти данных Numpy, как это
>>> anp = array([1,2,3])
array([1, 2, 3])
>>> anp.ctypes.data
40546992
Я могу отбросить его в void *, как это, ctypes и numpy:
>>> anp.ctypes.data_as(ctypes.c_void_p)
c_void_p(40546992)
Я пробовал бесконечные варианты. Что бы я ни делал, когда я вызываю свою функцию C, я получаю эту ошибку.
>>> myswig.myvoidp(anp.ctypes.data_as(ctypes.c_void_p))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: in method 'myvoidp', argument 1 of type 'void *'
Я не могу понять, как написать оператор Python/numpy, который позволяет мне (просто) передать указатель на мою функцию C. :-(
Я предполагаю, что вы хотите получить указатель на данные массива NumPy, чтобы вы могли получить доступ к элементам массива из C. NumPy поставляется с поддержкой SWIG, которую легко и удобно использовать. Просто загрузите numpy.i
и поместите его в каталог проекта.
Просто измените подпись функции C из (void *p)
на (double *data, int length)
и примените типовую карту NumPy.
test.i
%module example
%{
#define SWIG_FILE_WITH_INIT
#include <stdio.h>
void myvoidp(double *data, int length) {
printf("data = [ ");
for (int i = 0; i < length; ++i) {
printf("%f ", data[i]);
}
printf("]\n");
}
%}
%include "numpy.i"
%init %{
import_array();
%}
%apply (double* IN_ARRAY1, int DIM1) {(double *data, int length)}
void myvoidp(double *data, int length);
test.py
from example import myvoidp
from numpy import array
anp = array([1,2,3])
myvoidp(anp)
Пример вызова:
$ swig -python test.i
$ clang -Wall -Wextra -Wpedantic -I /usr/include/python3.6m/ -fPIC -shared -o _example.so test_wrap.c -lpython3.6m
$ python3 test.py
data = [ 1.000000 2.000000 3.000000 ]
myswig.myvoidp(ctypes.c_void_p(40546992))
лиmyswig.myvoidp(ctypes.c_void_p(40546992))
? Если нет, то вы можете устранитьnumpy
из вопроса