Don't use SEH when compiling wth mingw.
Use IS_INTRESOURCE to determine function name from function ordinal.
Rewrite the code that allocates and frees callback functions, hopefully
this avoids the coverty warnings: Remove the THUNK typedef, and move the
definition of struct ffi_info into the header file.
#include <ffi.h>
#ifdef MS_WIN32
#include <windows.h>
+#include <malloc.h>
+#ifndef IS_INTRESOURCE
+#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
+#endif
# ifdef _WIN32_WCE
/* Unlike desktop Windows, WinCE has both W and A variants of
GetProcAddress, but the default W version is not what we want */
funcname -> _funcname@<n>
where n is 0, 4, 8, 12, ..., 128
*/
- mangled_name = _alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
+ mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
for (i = 0; i < 32; ++i) {
sprintf(mangled_name, "_%s@%d", name, i*4);
address = (PPROC)GetProcAddress(handle, mangled_name);
#ifdef MS_WIN32
address = FindAddress(handle, name, (PyObject *)type);
if (!address) {
- if ((size_t)name & ~0xFFFF)
+ if (!IS_INTRESOURCE(name))
PyErr_Format(PyExc_AttributeError,
"function '%s' not found",
name);
else
PyErr_Format(PyExc_AttributeError,
"function ordinal %d not found",
- name);
+ (WORD)(size_t)name);
return NULL;
}
#else
CFuncPtrObject *self;
PyObject *callable;
StgDictObject *dict;
- THUNK thunk;
+ ffi_info *thunk;
if (PyTuple_GET_SIZE(args) == 0)
return GenericCData_new(type, args, kwds);
Py_CLEAR(self->paramflags);
if (self->thunk) {
- FreeCallback(self->thunk);
+ FreeClosure(self->thunk->pcl);
PyMem_Free(self->thunk);
+ self->thunk = NULL;
}
- self->thunk = NULL;
return CData_clear((CDataObject *)self);
}
PyGILState_Release(state);
}
-typedef struct {
- ffi_closure *pcl; /* the C callable */
- ffi_cif cif;
- PyObject *converters;
- PyObject *callable;
- SETFUNC setfunc;
- ffi_type *restype;
- ffi_type *atypes[0];
-} ffi_info;
-
static void closure_fcn(ffi_cif *cif,
void *resp,
void **args,
args);
}
-void FreeCallback(THUNK thunk)
-{
- FreeClosure(((ffi_info *)thunk)->pcl);
-}
-
-THUNK AllocFunctionCallback(PyObject *callable,
- PyObject *converters,
- PyObject *restype,
- int is_cdecl)
+ffi_info *AllocFunctionCallback(PyObject *callable,
+ PyObject *converters,
+ PyObject *restype,
+ int is_cdecl)
{
int result;
ffi_info *p;
nArgs = PySequence_Size(converters);
p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
- if (p == NULL)
- return (THUNK)PyErr_NoMemory();
+ if (p == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
p->pcl = MallocClosure();
if (p->pcl == NULL) {
PyErr_NoMemory();
p->converters = converters;
p->callable = callable;
- return (THUNK)p;
+ return p;
error:
if (p) {
- FreeCallback((THUNK)p);
+ if (p->pcl)
+ FreeClosure(p->pcl);
PyMem_Free(p);
}
return NULL;
#endif
#ifdef MS_WIN32
-#define alloca _alloca
+#include <malloc.h>
#endif
#include <ffi.h>
#include "ctypes.h"
-#ifdef _DEBUG
-#define DEBUG_EXCEPTIONS /* */
+#if defined(_DEBUG) || defined(__MINGW32__)
+/* Don't use structured exception handling on Windows if this is defined.
+ MingW, AFAIK, doesn't support it.
+*/
+#define DONT_USE_SEH
#endif
#ifdef MS_WIN32
return lpMsgBuf;
}
+#ifndef DONT_USE_SEH
void SetException(DWORD code, EXCEPTION_RECORD *pr)
{
TCHAR *lpMsgBuf;
*record = *ptrs->ExceptionRecord;
return EXCEPTION_EXECUTE_HANDLER;
}
+#endif
static PyObject *
check_hresult(PyObject *self, PyObject *args)
int cc;
#ifdef MS_WIN32
int delta;
+#ifndef DONT_USE_SEH
DWORD dwExceptionCode = 0;
EXCEPTION_RECORD record;
+#endif
#endif
/* XXX check before here */
if (restype == NULL) {
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_UNBLOCK_THREADS
#ifdef MS_WIN32
-#ifndef DEBUG_EXCEPTIONS
+#ifndef DONT_USE_SEH
__try {
#endif
delta =
#endif
ffi_call(&cif, (void *)pProc, resmem, avalues);
#ifdef MS_WIN32
-#ifndef DEBUG_EXCEPTIONS
+#ifndef DONT_USE_SEH
}
__except (HandleException(GetExceptionInformation(),
&dwExceptionCode, &record)) {
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_BLOCK_THREADS
#ifdef MS_WIN32
+#ifndef DONT_USE_SEH
if (dwExceptionCode) {
SetException(dwExceptionCode, &record);
return -1;
}
+#endif
if (delta < 0) {
if (flags & FUNCFLAG_CDECL)
PyErr_Format(PyExc_ValueError,
#define PY_LONG_LONG LONG_LONG
#endif
-typedef int (*THUNK)(void);
typedef struct tagCDataObject CDataObject;
+typedef PyObject *(* GETFUNC)(void *, unsigned size);
+typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
/* A default buffer in CDataObject, which can be used for small C types. If
this buffer is too small, PyMem_Malloc will be called to create a larger one,
union value b_value;
};
+typedef struct {
+ ffi_closure *pcl; /* the C callable */
+ ffi_cif cif;
+ PyObject *converters;
+ PyObject *callable;
+ SETFUNC setfunc;
+ ffi_type *restype;
+ ffi_type *atypes[0];
+} ffi_info;
+
typedef struct {
/* First part identical to tagCDataObject */
PyObject_HEAD
union value b_value;
/* end of tagCDataObject, additional fields follow */
- THUNK thunk;
+ ffi_info *thunk;
PyObject *callable;
/* These two fields will override the ones in the type's stgdict if
extern void init_callbacks_in_module(PyObject *m);
-extern THUNK AllocFunctionCallback(PyObject *callable,
- PyObject *converters,
- PyObject *restype,
- int stdcall);
-extern void FreeCallback(THUNK);
-
extern PyMethodDef module_methods[];
-typedef PyObject *(* GETFUNC)(void *, unsigned size);
-typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
-
+extern ffi_info *AllocFunctionCallback(PyObject *callable,
+ PyObject *converters,
+ PyObject *restype,
+ int stdcall);
/* a table entry describing a predefined ctypes type */
struct fielddesc {
char code;