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.
3
  • 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. Commented Jul 13, 2023 at 22:34
  • I also quite like using ctypes for this sometimes: stackoverflow.com/a/34457964/168175 Commented Jul 15, 2023 at 9:51
  • Hmm actually this is something I could probably make "just work" with a clever typemap in swig itself... Commented Jul 15, 2023 at 9:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.