TypeError: in method '...', argument 1 of type 'unsigned char const *' when using swig module
TypeError: in method '...', argument 1 of type 'unsigned char const *' when using swig module
考虑一下这个小痛饮 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 Whosebug""",
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 *'
请问,如何避免上述错误?
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;
= (unsigned char*)buffer;
%}
%include "example.h"
考虑一下这个小痛饮 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 Whosebug""",
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 *'
请问,如何避免上述错误?
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;
= (unsigned char*)buffer;
%}
%include "example.h"