首页 > 解决方案 > 通过 SWIG 将 Python 3 个字节输入到 C char*

问题描述

我试图围绕用 C 编写的 SWT 算法创建一个包装器。
我发现这篇文章和那里的代码在 python 2.7 中完美运行,但是当我尝试从 python 3 运行它时,出现错误:
in method 'swt', argument 1 of type 'char *'.

据我所知,这是因为open(img_filename, 'rb').read()在 python 2.7 中返回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);

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

标签: cpython-3.xswig

解决方案


您错误地使用了多参数类型映射。多参数类型映射必须具有具体的参数名称。否则,在不需要的情况下,它们会过于贪婪地匹配。要从 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

推荐阅读