-1

I have a C file that is wrapped with swig. This C file contains an API with function pointer as an argument(shown below).

example.c

int binary_op (int a, int b, int (*op)(int,int))
{
    return (*op)(a,b);
}

I can map a function to the pointer argument provided that mapping function is defined in same file using swig. But the mapping function is defined in another C file which is wrapped with Ctypes.

testing.c

int add_int(int a, int b){
     return a+b;
}

In Python, I imported swig generated module and called the API with ctypes generated mapping function, it resulted error.

In testfile.py

import example # Module generated by swig

from ctypes import *
wrap_dll = CDLL('testing.dll') # testing.dll is generated with File_2.c

# Mapping function 'add_int' to argument in 'binary_op'
example.binary_op(3,4,wrap_dll.add_int)

The error shown is the type of argument is not matching.

TypeError: in method 'binary_op', argument 3  of type 'int (*)(int,int)'
  • We have an error, no code and no question. One out of three for an [mcve], please try to do better. – Anthon Jul 11 '17 at 11:17
  • Search in here for callback, SWIG and Python and you will find something that you can use. It is there – Jens Munk Jul 11 '17 at 11:19
  • @JensMunk: I have searched quiet a lot but nothing seems related. Any help would be appreciated in case if you able to guide me to related stuff. Thanks – Maha Prakash Jul 12 '17 at 13:15
  • @Anthon Try take a look at this. https://stackoverflow.com/questions/34445045/passing-python-functions-to-swig-wrapped-c-code – Jens Munk Jul 12 '17 at 14:51
  • @JensMunk: Thanks for the link. I have managed to do the mapping between ctypes and swig wrapped functions. – Maha Prakash Jul 13 '17 at 15:48

1 Answers1

1

I have created a ctypes function like below in python:

py_callback_type = CFUNCTYPE(c_void_p, c_int, c_int)

where the return type and arguments type resembles the function pointer argument. Now I wrapped the mapping function 'add' to the above ctypes function.

f = py_callback_type(add)

And finally I casted the wrapped function with return type as pointer and the '.value' gives the address of the wrapped pointer function.

f_ptr = cast(f, c_void_p).value

Then in the swig interface file, using typemaps, I have changed the pointer argument as below:

extern int binary_op (int a, int b, int INPUT);

Now when I map the function to the pointer, the address of the mapping function will be passed as an integer INPUT to the binary_op function. Since the argument is a pointer, the function in the address will be mapped.

example.binary_op(4,5,f_ptr) ==> 9 //mapped function is 'add(int a, int b)' --> returns a+b