2

The problem I'm currently facing is to assign a python function to a C structure member variable that is a function pointer.

I get the error from the setter function generated by Swig when we call the SWIG_ConvertFunctionPtr for the assigned value stating that the expected type is not correct. For the sake of simplicity lets consider (void*) function pointer.

C code:

typedef void (*MyFunctionPtr)();

struct MyStruct {
    MyFunctionPtr func;
};

Python Code:

import example 
def my_python_function():
    print("Hello from Python!")

my_struct = example.MyStruct()
my_struct.func = my_python_function

the assignment would throw a run time error.

I did not add anything in my swig code to handle this except for including the header file. I wasn't able to find any tricks from the documentation or other forums. I won't be able to modify the C code, hence looking for solutions via python/swig.

Do you happen to have any ideas regarding how I can workaround this? Any pointers would be really helpful.

Edit (experiments):

Expt 1: typemap to typecast the input to void pointer (but still got the same error for mismatched type)

%typemap(in) void* MyFunctionPtr %{
  PyObject *func;
  if (PyCallable_Check($input)) {
    func = $input;
  } else {
    PyErr_SetString(PyExc_TypeError, "funcptr must be a callable object");
    return NULL;
  }
  $1 = (void*)func;
%}

Expt 2: I came across the following trick for C callback in swig. But in this case they are passing the python function as a PyObject and then type casting it to void in the function arguments.

http://www.fifi.org/doc/swig-examples/python/callback/widget.i

Still won't be able to achieve the structure assignment in this case.

Partial Solution:

  • created a global PyObject* to store the function. (Bad design according to swig)
  • override the constructor of the structure to accept the function as an input and assign it to the global variable.
Maverickgugu
  • 767
  • 4
  • 13
  • 26
  • 2
    This is actually relatively complicated because a python function is not a C function, and must be wrapped in a C function that calls the python function. See the PyCallback implementation in [this answer](https://stackoverflow.com/a/11522655/235698). – Mark Tolonen Jul 13 '23 at 22:34
  • I also quite like using ctypes for this sometimes: https://stackoverflow.com/a/34457964/168175 – Flexo Jul 15 '23 at 09:51
  • Hmm actually this is something I could probably make "just work" with a clever typemap in swig itself... – Flexo Jul 15 '23 at 09:55

0 Answers0