Include <malloc.h> on windows, to avoid warnings when compiling with mingw.
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.
This commit is contained in:
parent
c61c049955
commit
59feb6f5cc
|
@ -105,6 +105,10 @@ bytes(cdata)
|
|||
#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 */
|
||||
|
@ -2402,7 +2406,7 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type)
|
|||
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);
|
||||
|
@ -2557,14 +2561,14 @@ CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
#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
|
||||
|
@ -2651,7 +2655,7 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
CFuncPtrObject *self;
|
||||
PyObject *callable;
|
||||
StgDictObject *dict;
|
||||
THUNK thunk;
|
||||
ffi_info *thunk;
|
||||
|
||||
if (PyTuple_GET_SIZE(args) == 0)
|
||||
return GenericCData_new(type, args, kwds);
|
||||
|
@ -3192,10 +3196,10 @@ CFuncPtr_clear(CFuncPtrObject *self)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -264,16 +264,6 @@ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
|
|||
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,
|
||||
|
@ -289,15 +279,10 @@ static void closure_fcn(ffi_cif *cif,
|
|||
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;
|
||||
|
@ -306,8 +291,10 @@ THUNK AllocFunctionCallback(PyObject *callable,
|
|||
|
||||
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();
|
||||
|
@ -356,11 +343,12 @@ THUNK AllocFunctionCallback(PyObject *callable,
|
|||
|
||||
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;
|
||||
|
|
|
@ -64,14 +64,17 @@
|
|||
#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
|
||||
|
@ -96,6 +99,7 @@ static TCHAR *FormatError(DWORD code)
|
|||
return lpMsgBuf;
|
||||
}
|
||||
|
||||
#ifndef DONT_USE_SEH
|
||||
void SetException(DWORD code, EXCEPTION_RECORD *pr)
|
||||
{
|
||||
TCHAR *lpMsgBuf;
|
||||
|
@ -254,6 +258,7 @@ static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
|
|||
*record = *ptrs->ExceptionRecord;
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
check_hresult(PyObject *self, PyObject *args)
|
||||
|
@ -612,8 +617,10 @@ static int _call_function_pointer(int flags,
|
|||
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) {
|
||||
|
@ -640,14 +647,14 @@ static int _call_function_pointer(int flags,
|
|||
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)) {
|
||||
|
@ -658,10 +665,12 @@ static int _call_function_pointer(int flags,
|
|||
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,
|
||||
|
|
|
@ -21,8 +21,9 @@ typedef int Py_ssize_t;
|
|||
#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,
|
||||
|
@ -62,6 +63,16 @@ struct tagCDataObject {
|
|||
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
|
||||
|
@ -76,7 +87,7 @@ typedef struct {
|
|||
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
|
||||
|
@ -145,17 +156,12 @@ CreateArrayType(PyObject *itemtype, Py_ssize_t length);
|
|||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue