diff -Naur Python-2.7.9/Lib/ctypes/test/test_win32.py Python-2.7.9-mod/Lib/ctypes/test/test_win32.py --- Python-2.7.9/Lib/ctypes/test/test_win32.py Wed Dec 10 15:59:33 2014 +++ Python-2.7.9-mod/Lib/ctypes/test/test_win32.py Wed Mar 25 12:10:48 2015 @@ -113,6 +113,48 @@ self.assertEqual(ret.right, right.value) self.assertEqual(ret.top, top.value) self.assertEqual(ret.bottom, bottom.value) + def test_struct_callback(self): + class POINT(Structure): + _fields_ = [("x", c_long), + ("y", c_long)] + + class RECT(Structure): + _fields_ = [("left", c_long), + ("top", c_long), + ("right", c_long), + ("bottom", c_long)] + + dll = CDLL(_ctypes_test.__file__) + + callback_RECT = CFUNCTYPE(c_int, RECT) + callback_POINT = CFUNCTYPE(c_int, POINT) + + rect = RECT( 10,20,30,40 ) + def check_RECT(cb_rect): + if cb_rect.left != rect.left: + return 0 + if cb_rect.top != rect.top: + return 0 + if cb_rect.right != rect.right: + return 0 + if cb_rect.bottom != rect.bottom: + return 0 + return 1 + + result = dll.callback_RECT_test( rect, callback_RECT( check_RECT )) + self.assertEqual(result, 1) + + point = POINT( 100,200 ) + def check_POINT(cb_pt): + if cb_pt.x != point.x: + return 0 + if cb_pt.y != point.y: + return 0 + return 1 + + result = dll.callback_POINT_test( point, callback_POINT( check_POINT )) + self.assertEqual(result, 1) + if __name__ == '__main__': unittest.main() diff -Naur Python-2.7.9/Modules/_ctypes/_ctypes_test.c Python-2.7.9-mod/Modules/_ctypes/_ctypes_test.c --- Python-2.7.9/Modules/_ctypes/_ctypes_test.c Wed Dec 10 15:59:51 2014 +++ Python-2.7.9-mod/Modules/_ctypes/_ctypes_test.c Wed Mar 25 12:14:51 2015 @@ -583,6 +583,18 @@ return ar; } +typedef int (*callback_RECT)(RECT r); +typedef int (*callback_POINT)(POINT r); + +EXPORT(int) callback_RECT_test( RECT r, callback_RECT cb ) +{ + return cb(r); +} +EXPORT(int) callback_POINT_test( POINT p, callback_POINT cb ) +{ + return cb(p); +} + typedef struct { short x; short y; diff -Naur Python-2.7.9/Modules/_ctypes/libffi_msvc/ffi.c Python-2.7.9-mod/Modules/_ctypes/libffi_msvc/ffi.c --- Python-2.7.9/Modules/_ctypes/libffi_msvc/ffi.c Wed Dec 10 15:59:52 2014 +++ Python-2.7.9-mod/Modules/_ctypes/libffi_msvc/ffi.c Wed Mar 25 11:38:02 2015 @@ -377,7 +377,19 @@ /* because we're little endian, this is what it turns into. */ - *p_argv = (void*) argp; +#if _WIN64 + if ((*p_arg)->type == FFI_TYPE_STRUCT && z > 8) + { + z = 8; + *p_argv = *(void**)argp; + } + else + { + *p_argv = (void*) argp; + } +#else + *p_argv = (void*)argp; +#endif p_argv++; argp += z;