Ошибка типа: в методе '...', аргумент 1 типа 'unsigned char const *' при использовании модуля swig - PullRequest
0 голосов
/ 05 мая 2018

Рассмотрим этот маленький глоток mcve:

example.h

void init(int width, int height);
void dump(const unsigned char *buffer,int pitch);

example.c

#include <stdio.h>

void init(int width, int height) {
    printf("Initializing width=%d height=%d", width, height);
}

void dump(const unsigned char *buffer,int pitch) {
    for(int i=0;i<pitch;i++) {
        printf("%d\n", buffer[i]);
    }
}

example.i

%module example

%{
#include "example.h"
%}

%include "example.h"

setup.py

from distutils.core import setup, Extension


example_module = Extension('_example',
                            sources=['example.i', 'example_wrap.c', 'example.c'],
                            swig_opts = [],
                            include_dirs = ["."],
                           )

setup(name='example',
      version='0.1',
      author="BPL",
      description="""Mcve stackoverflow""",
      ext_modules=[example_module],
      py_modules=["example"]
    )

test.py

import struct
import example as swig_thing

count = 256
width = 8
height = 4

swig_thing.init(width, height)

for frame in range(count):
    print(f"frame {frame}")

    data = []
    for y in range(height):
        for x in range(width):
            data.append(0x00FF0000)
    _buffer = struct.pack(f'{len(data)}L', *data)
    swig_thing.dump(_buffer, width*4)

Если я запускаю python setup.py build_ext --inplace и затем пытаюсь запустить test.py, я получаю следующую ошибку:

TypeError: in method 'dump', argument 1 of type 'unsigned char const *'

Вопрос, как избежать вышеуказанной ошибки?

1 Ответ

0 голосов
/ 05 мая 2018

struct.pack может использоваться для создания буферов байтовых строк. Допустим, у вас есть четыре целых числа, которые можно упаковать как четыре беззнаковых длинных значения (16 байт). pack принимает строку формата. '4L' означает упаковку четырех длинных без знака в формате с прямым порядком байтов. Используйте '<4L' для байтов с прямым порядком байтов и '>4L' для байтов с прямым порядком байтов.

>>> import struct
>>> struct.pack('4L',1,2,3,4) # Direct way.
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'

>>> data = [1,2,3,4] # Handle variable length...
>>> struct.pack('{}L'.format(len(data)),*data) 
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'

>>> struct.pack(f'{len(data)}L',*data) # Python 3.6+
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'

Упражнение для создания списка данных ?

В соответствии с MCVE, добавьте следующую карту типов в интерфейс SWIG, чтобы понять unsigned char *:

example.i

%module example

%{
#include "example.h"
%}

%typemap(in) (const unsigned char* buffer) (char* buffer, Py_ssize_t length) %{
  if(PyBytes_AsStringAndSize($input,&buffer,&length) == -1)
    SWIG_fail;
  $1 = (unsigned char*)buffer;
%}

%include "example.h"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...