TypeError:在方法' ...'中,类型' unsigned char const *'的参数1使用swig模块时

时间:2018-05-05 00:56:37

标签: python swig

考虑一下这个小小的笑话:

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 :(得分:1)

struct.pack可用于创建字节串缓冲区。让我们假设您有四个整数打包为四个无符号长值(16个字节)。 pack采用格式字符串。 '4L'表示以native-endian格式打包四个unsigned long。将'<4L'用于little-endian,将'>4L'用于big-endian。

>>> 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"