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

Posted

技术标签:

【中文标题】TypeError:在方法“...”中,使用 swig 模块时类型为“unsigned char const *”的参数 1【英文标题】:TypeError: in method '...', argument 1 of type 'unsigned char const *' when using swig module 【发布时间】:2018-05-05 00:56:36 【问题描述】:

考虑一下这个小小的 swig 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 ***""",
      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】:

struct.pack 可用于创建字节字符串缓冲区。假设您有四个整数要打包为四个无符号长值(16 个字节)。 pack 采用格式字符串。 '4L' 表示以原生字节序格式打包四个无符号长整数。对小端使用'&lt;4L',对大端使用'&gt;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"

【讨论】:

这是由于 SWIG 中没有为 unsigned char * 定义类型映射。 @BPL 我更新了我的答案。下次更改标题和问题的注意事项需要一个新问题。我最初的回答在新环境中没有意义。 @BPL 但是非常感谢 MCVE! @BPL 我试过你的代码。我没有意识到“pitch”(或您上传的代码中的“linepitch”)不是完整的缓冲区长度。我将上面的 example.i 更改为仅转换缓冲区指针。将“pitch”作为 width*4 传递,您的代码将起作用。我能够在您的 aviwriter 链接上构建代码并生成一个 .avi 文件。 如果您对这个主题感兴趣,我创建了一个小 mcve 来尝试渲染音频/视频。检查它 1) git clone github.com/brupelo/aviwriter 2) python setup.py build_ext --inplace 3) python test.py -audio=0 ,这将生成视频就好了。但是当我尝试生成音频python test.py -audio=1 时,生成的视频文件将被破坏,我不知道为什么,知道我做错了什么吗?你认为问题出在 python 代码或 swig 文件中?

以上是关于TypeError:在方法“...”中,使用 swig 模块时类型为“unsigned char const *”的参数 1的主要内容,如果未能解决你的问题,请参考以下文章

Python TypeError:预期的字符串或缓冲区

AngularJS指令元素方法绑定-TypeError:无法使用'in'运算符在1中搜索'functionName'

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

TypeError:“方法”对象不可迭代 MySQL

获取TypeError:无法在mysql node.js中调用null的方法'releaseConnection'

# 字符串方法 TypeError: 列在 pyspark 中不可迭代