Python передает пустой указатель в качестве параметра функции C (SWIG, Numpy)

1

Мне нужно передать указатель из 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. :-(

  • 0
    myswig.myvoidp(ctypes.c_void_p(40546992)) ли myswig.myvoidp(ctypes.c_void_p(40546992)) ? Если нет, то вы можете устранить numpy из вопроса
  • 0
    Хорошая идея. Да, это приводит к той же ошибке, так что numpy не играет. Я нашел способ заставить его работать в ctypes, хотя, я думаю, потому что в ctypes я указываю, что хочу передать указатель void в качестве первого аргумента.
Показать ещё 2 комментария
Теги:
numpy
pointers
swig

1 ответ

0

Я предполагаю, что вы хотите получить указатель на данные массива 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 ]
  • 0
    Здорово. Я попробую это. Спасибо :)
  • 0
    Может ли downvoter объяснить, где мой ответ отсутствует?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню