通过 SWIG 将 Python 3 个字节输入到 C char*

Posted

技术标签:

【中文标题】通过 SWIG 将 Python 3 个字节输入到 C char*【英文标题】:Input Python 3 bytes to C char* via SWIG 【发布时间】:2018-07-19 16:13:54 【问题描述】:

我正在尝试围绕用 C 编写的 SWT 算法创建一个包装器。 我找到了this post,并且那里的代码在 python 2.7 中完美运行,但是当我尝试从 python 3 运行它时,出现错误:in method 'swt', argument 1 of type 'char *'

据我所知,这是因为python 2.7中的open(img_filename, 'rb').read()返回string类型,但在python 3中它是bytes类型。

我尝试用下面的代码修改ccvwrapper.i,但没有成功

%typemap(in) char, int, int, int 
     $1 = PyBytes_AS_STRING($1);

函数标题: int* swt(char *bytes, int array_length, int width, int height);

如何通过 SWIG 将 python3 bytes 传递给该函数?

【问题讨论】:

【参考方案1】:

您错误地使用了多参数类型映射。多参数类型映射必须具有具体的参数名称。否则,在不需要的情况下,它们会过于贪婪地匹配。要从 Python 获取缓冲区的字节数和长度,请使用 PyBytes_AsStringAndSize

test.i

%module example
%
int* swt(char *bytes, int array_length, int width, int height) 
    printf("bytes = %s\narray_length = %d\nwidth = %d\nheight = %d\n",
           bytes, array_length, width, height);
    return NULL;

%

%typemap(in) (char *bytes, int array_length) 
    Py_ssize_t len;
    PyBytes_AsStringAndSize($input, &$1, &len);
    $2 = (int)len;


int* swt(char *bytes, int array_length, int width, int height);

test.py

from example import *
swt(b"Hello World!", 100, 50)

调用示例:

$ swig -python -py3 test.i
$ clang -Wall -Wextra -Wpedantic -I /usr/include/python3.6/ -fPIC -shared test_wrap.c -o _example.so -lpython3.6m
$ python3 test.py 
bytes = Hello World!
array_length = 12
width = 100
height = 50

【讨论】:

【参考方案2】:
%module example
%begin %
#define SWIG_PYTHON_STRICT_BYTE_CHAR
%
int* swt(char *bytes, int array_length, int width, int height);

【讨论】:

不错的一个!这比自定义输入类型映射要容易得多。

以上是关于通过 SWIG 将 Python 3 个字节输入到 C char*的主要内容,如果未能解决你的问题,请参考以下文章

SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构

SWIG 将 C++ 扩展到 Python,未定义的枚举

在 Mac 上的 Python 2.7.3 中导入 .pyd(使用 SWIG 创建)

SWIG 'cstring.i' Python 返回字节类型而不是字符串类型

使用 SWIG 将 C++ 文件包装为 Python 文件

python的swig typemap:输入和输出数组