Message85654
We have an application that calls a 3rd party library that returns a
structure (by value) from a callback. I'm including some sample code
that duplicates the behavior. The problem is that return types from
callbacks cannot be anything other than simple datatypes (c_int,
c_float, ..., c_void_p). For other datatypes (STRUCTURE, POINTER, ...),
ctypes returns the following error:
"invalid result type for callback function"
The error message comes from callback.c, in function AllocFunctionCallback.
I think this may be a duplicate of issue #1574584.
I've tested this on Windows and linux; I'm including a Makefile and
source code that works on Windows/cygwin.
------ file: Makefile ----
all: hello.dll hello.exe hello_dll.exe
clean:
rm *.exe *.dll
hello.exe: hello.h hello.c hello_main.c
gcc hello.c hello_main.c -o hello.exe --save-temps
hello.dll: hello.h hello.c
gcc -mno-cygwin -shared hello.c -o hello.dll --save-temps
hello_dll.exe: hello.h hello.c
gcc hello_main.c -L. -lhello -o hello_main.exe
------ file: hello.h ----
struct helloStruct {
int i;
float f;
int i2;
int i3;
};
float fxn (struct helloStruct callback());
------ file: hello.c ----
#include <stdio.h>
#include "hello.h"
float fxn (struct helloStruct callback()) {
struct helloStruct result = callback();
printf ("i: %d\n", result.i);
printf ("f: %f\n", result.f);
return result.f * result.i;
}
------ file: hello_main.c ----
#include <stdio.h>
#include "hello.h"
struct helloStruct callback();
int main (int argc, char **argv) {
float f;
struct helloStruct result;
printf ("Hello world\n");
f = fxn (callback);
printf ("Callback result: %f\n", f);
}
struct helloStruct callback () {
struct helloStruct result;
result.i = 10;
result.f = 3.14159;
return result;
}
int int_callback () {
return 42;
}
------ file: hello.py ----
from ctypes import cdll, c_char, c_int, c_float, Structure, CFUNCTYPE,
POINTER, c_char_p
class helloStruct (Structure):
pass
helloStruct._fields_ = [
('i', c_int),
('f', c_float) ]
def callback():
print ("callback()")
hs = helloStruct()
hs.i = 10
hs.f = 25.5
return hs
libc = cdll.msvcrt
#helloLib = libc.load_library("hello")
#helloLib = libc.hello
helloLib = cdll.hello
helloLib.fxn.restype = helloStruct
# It looks like only simple return types are supported for
# callback functions. simple = c_int, c_float, ...
# Python bug # 1574584 - status: closed.
# Suggests posting to ctypes-users, but I don't see any recent activity.
#
TMP_FCN = CFUNCTYPE (POINTER(c_char)) # Error message
#TMP_FCN = CFUNCTYPE (c_char_p) # Runs, but invalid result
#TMP_FCN = CFUNCTYPE (c_void_p) # Runs, but invalid result
#TMP_FCN = CFUNCTYPE (c_int) # Runs, but invalid result
#TMP_FCN = CFUNCTYPE (POINTER(c_int)) # Error message
#TMP_FCN = CFUNCTYPE (POINTER(helloStruct)) # Error message
#TMP_FCN = CFUNCTYPE (helloStruct) # Error message
callback_fcn = TMP_FCN (callback)
result = helloLib.fxn (callback_fcn)
# 2.5
#print "result: ", result
# 3.0
print ("result: ", result) |
|
Date |
User |
Action |
Args |
2009-04-06 17:28:47 | gholling | set | recipients:
+ gholling, theller |
2009-04-06 17:28:46 | gholling | set | messageid: <1239038926.27.0.792638874347.issue5710@psf.upfronthosting.co.za> |
2009-04-06 17:28:43 | gholling | link | issue5710 messages |
2009-04-06 17:28:41 | gholling | create | |
|