Reputation: 7681
I'm trying to use the ctypes callback feature to pass a python function to a C function as a function pointer. Here's the C:
typedef void(*f1)();
void function_that_takes_a_function(f1* fn){
printf("I'm a function that takes a function\n");
double d1[2] = {0.1, 0.2} ;
printf("1\n");
double *d2;
printf("2\n");
double *g;
printf("3\n");
printf("%d\n", (long )fn);
(*fn)();
printf("4\n");
}
And the Python
import ctypes as ct
lib = ct.CDLL("SRES")
F1_CALLBACK = ct.CFUNCTYPE(None)
function_that_takes_a_function = lib.function_that_takes_a_function
function_that_takes_a_function.argtypes = [F1_CALLBACK]
function_that_takes_a_function.restype = None
@F1_CALLBACK
def func_to_pass_in():
print("hello from Python")
function_that_takes_a_function(func_to_pass_in)
This gives me
I'm a function that takes a function
1
2
3
-1788276848
Error
Traceback (most recent call last):
File "C:\Miniconda3\envs\py38\lib\unittest\case.py", line 60, in testPartExecutor
yield
File "C:\Miniconda3\envs\py38\lib\unittest\case.py", line 676, in run
self._callTestMethod(testMethod)
File "C:\Miniconda3\envs\py38\lib\unittest\case.py", line 633, in _callTestMethod
method()
File "Guassianproblem.py", line 77, in testFunctionPointerInIsolation
function_that_takes_a_function(func_to_pass_in)
OSError: exception: access violation writing 0xFFFFFFFFF9158D4C
Where I expect to see:
I'm a function that takes a function
1
2
3
Hello from Python
4
Can anybody spot my problem?
Upvotes: 1
Views: 321
Reputation: 441
f1
is already a pointer to a function with return type void
and no parameter (see type definition).
The following works.
typedef void(*f1)();
void function_that_takes_a_function(f1 fn)
{
fn();
}
with the following Python code:
import ctypes as ct
lib = ct.CDLL("SRES")
F1_CALLBACK = ct.CFUNCTYPE(None)
function_that_takes_a_function = lib.function_that_takes_a_function
function_that_takes_a_function.argtypes = [F1_CALLBACK]
function_that_takes_a_function.restype = None
@F1_CALLBACK
def func_to_pass_in():
print("hello from Python")
function_that_takes_a_function(func_to_pass_in)
Upvotes: 2