首页 > 解决方案 > TypeError:在方法“...”中,使用 swig 模块时类型为“unsigned char const *”的参数 1

问题描述

考虑一下这个小小的 swig mcve:

例子.h

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

例子.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]);
    }
}

例子.i

%module example

%{
#include "example.h"
%}

%include "example.h"

安装程序.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"]
    )

测试.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 *'

问题,如何避免上述错误?

标签: pythonswig

解决方案


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 *

例子.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"

推荐阅读