2
#include "frameobject.h"
10
/**************************************************************/
13
CThunkObject_dealloc(PyObject *myself)
15
CThunkObject *self = (CThunkObject *)myself;
16
PyObject_GC_UnTrack(self);
17
Py_XDECREF(self->converters);
18
Py_XDECREF(self->callable);
19
Py_XDECREF(self->restype);
21
ffi_closure_free(self->pcl_write);
22
PyObject_GC_Del(self);
26
CThunkObject_traverse(PyObject *myself, visitproc visit, void *arg)
28
CThunkObject *self = (CThunkObject *)myself;
29
Py_VISIT(self->converters);
30
Py_VISIT(self->callable);
31
Py_VISIT(self->restype);
36
CThunkObject_clear(PyObject *myself)
38
CThunkObject *self = (CThunkObject *)myself;
39
Py_CLEAR(self->converters);
40
Py_CLEAR(self->callable);
41
Py_CLEAR(self->restype);
45
PyTypeObject PyCThunk_Type = {
46
PyVarObject_HEAD_INIT(NULL, 0)
47
"_ctypes.CThunkObject",
48
sizeof(CThunkObject), /* tp_basicsize */
49
sizeof(ffi_type), /* tp_itemsize */
50
CThunkObject_dealloc, /* tp_dealloc */
57
0, /* tp_as_sequence */
58
0, /* tp_as_mapping */
65
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
66
"CThunkObject", /* tp_doc */
67
CThunkObject_traverse, /* tp_traverse */
68
CThunkObject_clear, /* tp_clear */
69
0, /* tp_richcompare */
70
0, /* tp_weaklistoffset */
77
/**************************************************************/
80
PrintError(char *msg, ...)
83
PyObject *f = PySys_GetObject("stderr");
86
va_start(marker, msg);
87
vsnprintf(buf, sizeof(buf), msg, marker);
89
if (f != NULL && f != Py_None)
90
PyFile_WriteString(buf, f);
95
/* after code that pyrex generates */
96
void _ctypes_add_traceback(char *funcname, char *filename, int lineno)
98
PyObject *py_globals = 0;
99
PyCodeObject *py_code = 0;
100
PyFrameObject *py_frame = 0;
101
PyObject *exception, *value, *tb;
103
/* (Save and) Clear the current exception. Python functions must not be
104
called with an exception set. Calling Python functions happens when
105
the codec of the filesystem encoding is implemented in pure Python. */
106
PyErr_Fetch(&exception, &value, &tb);
108
py_globals = PyDict_New();
111
py_code = PyCode_NewEmpty(filename, funcname, lineno);
114
py_frame = PyFrame_New(
115
PyThreadState_Get(), /*PyThreadState *tstate,*/
116
py_code, /*PyCodeObject *code,*/
117
py_globals, /*PyObject *globals,*/
118
0 /*PyObject *locals*/
122
py_frame->f_lineno = lineno;
124
PyErr_Restore(exception, value, tb);
125
PyTraceBack_Here(py_frame);
127
Py_DECREF(py_globals);
133
Py_XDECREF(py_globals);
135
Py_XDECREF(py_frame);
140
* We must call AddRef() on non-NULL COM pointers we receive as arguments
141
* to callback functions - these functions are COM method implementations.
142
* The Python instances we create have a __del__ method which calls Release().
144
* The presence of a class attribute named '_needs_com_addref_' triggers this
145
* behaviour. It would also be possible to call the AddRef() Python method,
146
* after checking for PyObject_IsTrue(), but this would probably be somewhat
150
TryAddRef(StgDictObject *dict, CDataObject *obj)
154
if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
157
punk = *(IUnknown **)obj->b_ptr;
159
punk->lpVtbl->AddRef(punk);
164
/******************************************************************************
166
* Call the python object with all arguments
169
static void _CallPythonObject(void *mem,
173
PyObject *converters,
179
PyObject *arglist = NULL;
181
PyObject *error_object = NULL;
184
PyGILState_STATE state = PyGILState_Ensure();
187
nArgs = PySequence_Length(converters);
188
/* Hm. What to return in case of error?
189
For COM, 0xFFFFFFFF seems better than 0.
192
PrintError("BUG: PySequence_Length");
196
arglist = PyTuple_New(nArgs);
198
PrintError("PyTuple_New()");
201
for (i = 0; i < nArgs; ++i) {
202
/* Note: new reference! */
203
PyObject *cnv = PySequence_GetItem(converters, i);
206
dict = PyType_stgdict(cnv);
208
PrintError("Getting argument converter %d\n", i);
212
if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) {
213
PyObject *v = dict->getfunc(*pArgs, dict->size);
215
PrintError("create argument %d:\n", i);
219
PyTuple_SET_ITEM(arglist, i, v);
221
We have the problem that c_byte or c_short have dict->size of
222
1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
223
BTW, the same problem occurs when they are pushed as parameters
226
/* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */
227
CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
229
PrintError("create argument %d:\n", i);
233
if (!CDataObject_Check(obj)) {
236
PrintError("unexpected result of create argument %d:\n", i);
239
memcpy(obj->b_ptr, *pArgs, dict->size);
240
PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
242
TryAddRef(dict, obj);
245
PyErr_SetString(PyExc_TypeError,
246
"cannot build parameter");
247
PrintError("Parsing argument %d\n", i);
252
/* XXX error handling! */
256
#define CHECK(what, x) \
257
if (x == NULL) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
259
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
260
error_object = _ctypes_get_errobj(&space);
261
if (error_object == NULL)
263
if (flags & FUNCFLAG_USE_ERRNO) {
269
if (flags & FUNCFLAG_USE_LASTERROR) {
271
space[1] = GetLastError();
277
result = PyObject_CallObject(callable, arglist);
278
CHECK("'calling callback function'", result);
281
if (flags & FUNCFLAG_USE_LASTERROR) {
283
space[1] = GetLastError();
287
if (flags & FUNCFLAG_USE_ERRNO) {
292
Py_XDECREF(error_object);
294
if ((restype != &ffi_type_void) && result) {
297
#ifdef WORDS_BIGENDIAN
298
/* See the corresponding code in callproc.c, around line 961 */
299
if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
300
mem = (char *)mem + sizeof(ffi_arg) - restype->size;
302
keep = setfunc(mem, result, 0);
303
CHECK("'converting callback result'", keep);
304
/* keep is an object we have to keep alive so that the result
305
stays valid. If there is no such object, the setfunc will
306
have returned Py_None.
308
If there is such an object, we have no choice than to keep
309
it alive forever - but a refcount and/or memory leak will
310
be the result. EXCEPT when restype is py_object - Python
311
itself knows how to manage the refcount of these objects.
313
if (keep == NULL) /* Could not convert callback result. */
314
PyErr_WriteUnraisable(callable);
315
else if (keep == Py_None) /* Nothing to keep */
317
else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) {
318
if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning,
319
"memory leak in callback function.",
321
PyErr_WriteUnraisable(callable);
328
PyGILState_Release(state);
332
static void closure_fcn(ffi_cif *cif,
337
CThunkObject *p = (CThunkObject *)userdata;
339
_CallPythonObject(resp,
348
static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
353
p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
361
memset(&p->cif, 0, sizeof(p->cif));
362
p->converters = NULL;
365
p->ffi_restype = NULL;
367
for (i = 0; i < nArgs + 1; ++i)
369
PyObject_GC_Track((PyObject *)p);
373
CThunkObject *_ctypes_alloc_callback(PyObject *callable,
374
PyObject *converters,
383
nArgs = PySequence_Size(converters);
384
p = CThunkObject_new(nArgs);
388
assert(CThunk_CheckExact((PyObject *)p));
390
p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
392
if (p->pcl_write == NULL) {
398
for (i = 0; i < nArgs; ++i) {
399
PyObject *cnv = PySequence_GetItem(converters, i);
402
p->atypes[i] = _ctypes_get_ffi_type(cnv);
408
p->restype = restype;
409
if (restype == Py_None) {
411
p->ffi_restype = &ffi_type_void;
413
StgDictObject *dict = PyType_stgdict(restype);
414
if (dict == NULL || dict->setfunc == NULL) {
415
PyErr_SetString(PyExc_TypeError,
416
"invalid result type for callback function");
419
p->setfunc = dict->setfunc;
420
p->ffi_restype = &dict->ffi_type_pointer;
423
cc = FFI_DEFAULT_ABI;
424
#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
425
if ((flags & FUNCFLAG_CDECL) == 0)
428
result = ffi_prep_cif(&p->cif, cc,
429
Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
430
_ctypes_get_ffi_type(restype),
432
if (result != FFI_OK) {
433
PyErr_Format(PyExc_RuntimeError,
434
"ffi_prep_cif failed with %d", result);
437
#if defined(X86_DARWIN) || defined(POWERPC_DARWIN)
438
result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
440
result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
444
if (result != FFI_OK) {
445
PyErr_Format(PyExc_RuntimeError,
446
"ffi_prep_closure failed with %d", result);
450
Py_INCREF(converters);
451
p->converters = converters;
453
p->callable = callable;
463
static void LoadPython(void)
465
if (!Py_IsInitialized()) {
467
PyEval_InitThreads();
473
/******************************************************************/
475
long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
477
PyObject *mod, *func, *result;
479
static PyObject *context;
482
context = PyUnicode_InternFromString("_ctypes.DllGetClassObject");
484
mod = PyImport_ImportModuleNoBlock("ctypes");
486
PyErr_WriteUnraisable(context ? context : Py_None);
487
/* There has been a warning before about this already */
491
func = PyObject_GetAttrString(mod, "DllGetClassObject");
494
PyErr_WriteUnraisable(context ? context : Py_None);
499
PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid);
500
PyObject *py_riid = PyLong_FromVoidPtr((void *)riid);
501
PyObject *py_ppv = PyLong_FromVoidPtr(ppv);
502
if (!py_rclsid || !py_riid || !py_ppv) {
503
Py_XDECREF(py_rclsid);
507
PyErr_WriteUnraisable(context ? context : Py_None);
510
result = PyObject_CallFunctionObjArgs(func,
515
Py_DECREF(py_rclsid);
521
PyErr_WriteUnraisable(context ? context : Py_None);
525
retval = PyLong_AsLong(result);
526
if (PyErr_Occurred()) {
527
PyErr_WriteUnraisable(context ? context : Py_None);
534
STDAPI DllGetClassObject(REFCLSID rclsid,
540
PyGILState_STATE state;
545
state = PyGILState_Ensure();
547
result = Call_GetClassObject(rclsid, riid, ppv);
549
PyGILState_Release(state);
554
long Call_CanUnloadNow(void)
556
PyObject *mod, *func, *result;
558
static PyObject *context;
561
context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow");
563
mod = PyImport_ImportModuleNoBlock("ctypes");
565
/* OutputDebugString("Could not import ctypes"); */
566
/* We assume that this error can only occur when shutting
567
down, so we silently ignore it */
571
/* Other errors cannot be raised, but are printed to stderr */
572
func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
575
PyErr_WriteUnraisable(context ? context : Py_None);
579
result = PyObject_CallFunction(func, NULL);
582
PyErr_WriteUnraisable(context ? context : Py_None);
586
retval = PyLong_AsLong(result);
587
if (PyErr_Occurred()) {
588
PyErr_WriteUnraisable(context ? context : Py_None);
596
DllRegisterServer and DllUnregisterServer still missing
599
STDAPI DllCanUnloadNow(void)
603
PyGILState_STATE state = PyGILState_Ensure();
605
result = Call_CanUnloadNow();
607
PyGILState_Release(state);
612
#ifndef Py_NO_ENABLE_SHARED
613
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
616
case DLL_PROCESS_ATTACH:
617
DisableThreadLibraryCalls(hinstDLL);
628
compile-command: "cd .. && python setup.py -q build_ext"