Skip to content

Commit b102dda

Browse files
author
Thomas Heller
committed
Revert rev. 79509; ctypes doesn't build on linux.
1 parent 08b56b6 commit b102dda

18 files changed

Lines changed: 2072 additions & 379 deletions

File tree

Lib/ctypes/test/test_win32.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,32 @@
66

77
import _ctypes_test
88

9+
if sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int):
10+
# Only windows 32-bit has different calling conventions.
11+
12+
class WindowsTestCase(unittest.TestCase):
13+
def test_callconv_1(self):
14+
# Testing stdcall function
15+
16+
IsWindow = windll.user32.IsWindow
17+
# ValueError: Procedure probably called with not enough arguments (4 bytes missing)
18+
self.assertRaises(ValueError, IsWindow)
19+
20+
# This one should succeeed...
21+
self.assertEqual(0, IsWindow(0))
22+
23+
# ValueError: Procedure probably called with too many arguments (8 bytes in excess)
24+
self.assertRaises(ValueError, IsWindow, 0, 0, 0)
25+
26+
def test_callconv_2(self):
27+
# Calling stdcall function as cdecl
28+
29+
IsWindow = cdll.user32.IsWindow
30+
31+
# ValueError: Procedure called with not enough arguments (4 bytes missing)
32+
# or wrong calling convention
33+
self.assertRaises(ValueError, IsWindow, None)
34+
935
if sys.platform == "win32":
1036
class FunctionCallTestCase(unittest.TestCase):
1137

Modules/_ctypes/callbacks.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ CThunkObject_dealloc(PyObject *_self)
2222
Py_XDECREF(self->callable);
2323
Py_XDECREF(self->restype);
2424
if (self->pcl)
25-
ffi_closure_free(self->pcl);
25+
_ctypes_free_closure(self->pcl);
2626
PyObject_GC_Del(self);
2727
}
2828

@@ -421,7 +421,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
421421

422422
assert(CThunk_CheckExact(p));
423423

424-
if (ffi_closure_alloc(sizeof(ffi_closure), &p->pcl) == NULL) {
424+
p->pcl = _ctypes_alloc_closure();
425+
if (p->pcl == NULL) {
425426
PyErr_NoMemory();
426427
goto error;
427428
}

Modules/_ctypes/callproc.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,7 @@ static int _call_function_pointer(int flags,
771771
ffi_cif cif;
772772
int cc;
773773
#ifdef MS_WIN32
774+
int delta;
774775
#ifndef DONT_USE_SEH
775776
DWORD dwExceptionCode = 0;
776777
EXCEPTION_RECORD record;
@@ -821,8 +822,9 @@ static int _call_function_pointer(int flags,
821822
#ifndef DONT_USE_SEH
822823
__try {
823824
#endif
825+
delta =
824826
#endif
825-
ffi_call(&cif, (void *)pProc, resmem, avalues);
827+
ffi_call(&cif, (void *)pProc, resmem, avalues);
826828
#ifdef MS_WIN32
827829
#ifndef DONT_USE_SEH
828830
}
@@ -854,6 +856,35 @@ static int _call_function_pointer(int flags,
854856
return -1;
855857
}
856858
#endif
859+
#ifdef MS_WIN64
860+
if (delta != 0) {
861+
PyErr_Format(PyExc_RuntimeError,
862+
"ffi_call failed with code %d",
863+
delta);
864+
return -1;
865+
}
866+
#else
867+
if (delta < 0) {
868+
if (flags & FUNCFLAG_CDECL)
869+
PyErr_Format(PyExc_ValueError,
870+
"Procedure called with not enough "
871+
"arguments (%d bytes missing) "
872+
"or wrong calling convention",
873+
-delta);
874+
else
875+
PyErr_Format(PyExc_ValueError,
876+
"Procedure probably called with not enough "
877+
"arguments (%d bytes missing)",
878+
-delta);
879+
return -1;
880+
} else if (delta > 0) {
881+
PyErr_Format(PyExc_ValueError,
882+
"Procedure probably called with too many "
883+
"arguments (%d bytes in excess)",
884+
delta);
885+
return -1;
886+
}
887+
#endif
857888
#endif
858889
if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
859890
return -1;
@@ -1130,7 +1161,11 @@ PyObject *_ctypes_callproc(PPROC pProc,
11301161
}
11311162
for (i = 0; i < argcount; ++i) {
11321163
atypes[i] = args[i].ffi_type;
1133-
if (atypes[i]->type == FFI_TYPE_STRUCT)
1164+
if (atypes[i]->type == FFI_TYPE_STRUCT
1165+
#ifdef _WIN64
1166+
&& atypes[i]->size <= sizeof(void *)
1167+
#endif
1168+
)
11341169
avalues[i] = (void *)args[i].value.p;
11351170
else
11361171
avalues[i] = (void *)&args[i].value;

Modules/_ctypes/ctypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,9 @@ extern Py_ssize_t PyUnicode_AsWideChar_fixed(PyUnicodeObject *, wchar_t *, Py_ss
428428
#endif
429429
#endif
430430

431+
extern void _ctypes_free_closure(void *);
432+
extern void *_ctypes_alloc_closure(void);
433+
431434
extern void _ctypes_add_traceback(char *, char *, int);
432435

433436
extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
libffi - Copyright (c) 1996-2003 Red Hat, Inc.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
``Software''), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included
12+
in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+
IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+
OTHER DEALINGS IN THE SOFTWARE.

0 commit comments

Comments
 (0)