[issue5710] ctypes should return composite types from callbacks

Greg Holling report at bugs.python.org
Mon Apr 6 19:28:46 CEST 2009


New submission from Greg Holling <gholling at vni.com>:

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)

----------
assignee: theller
components: ctypes
messages: 85654
nosy: gholling, theller
severity: normal
status: open
title: ctypes should return composite types from callbacks
versions: Python 2.5, Python 2.6, Python 2.7, Python 3.0, Python 3.1

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue5710>
_______________________________________


More information about the Python-bugs-list mailing list