Reputation: 2505
Im trying to create a wrapper around SWT algorythm written on C.
I found this post and code from there is perfectly working in python 2.7, but when I am trying to run it from python 3, error emerges:
in method 'swt', argument 1 of type 'char *'
.
As far as I know, it is because open(img_filename, 'rb').read()
in python 2.7 returns string
type, but in python 3 it is a bytes
type.
I tried to modify ccvwrapper.i
with the code below but without success
%typemap(in) char, int, int, int {
$1 = PyBytes_AS_STRING($1);
}
Functions header:
int* swt(char *bytes, int array_length, int width, int height);
How I can pass python3 bytes
to that function via SWIG?
Upvotes: 4
Views: 2593
Reputation: 471
%module example
%begin %{
#define SWIG_PYTHON_STRICT_BYTE_CHAR
%}
int* swt(char *bytes, int array_length, int width, int height);
Upvotes: 4
Reputation: 10939
You are using multi-argument typemaps wrong. Multi-argument typemaps have to have concrete parameter names. Otherwise they'd match too greedily in situations where this is not desired. To get the bytes and the length of the buffer from Python use 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)
Example invocation:
$ 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
Upvotes: 4