Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Input Python 3 bytes to C char* via SWIG

Tags:

c

python-3.x

swig

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?

like image 923
banderlog013 Avatar asked Oct 17 '25 15:10

banderlog013


1 Answers

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
like image 117
Henri Menke Avatar answered Oct 20 '25 05:10

Henri Menke