1
/*****************************************************************
2
This file should be kept compatible with Python 2.3, see PEP 291.
3
*****************************************************************/
6
#include "compile.h" /* required only for 2.3, as it seems */
7
#include "frameobject.h"
15
/**************************************************************/
18
CThunkObject_dealloc(PyObject *_self)
20
CThunkObject *self = (CThunkObject *)_self;
21
Py_XDECREF(self->converters);
22
Py_XDECREF(self->callable);
23
Py_XDECREF(self->restype);
25
FreeClosure(self->pcl);
30
CThunkObject_traverse(PyObject *_self, visitproc visit, void *arg)
32
CThunkObject *self = (CThunkObject *)_self;
33
Py_VISIT(self->converters);
34
Py_VISIT(self->callable);
35
Py_VISIT(self->restype);
40
CThunkObject_clear(PyObject *_self)
42
CThunkObject *self = (CThunkObject *)_self;
43
Py_CLEAR(self->converters);
44
Py_CLEAR(self->callable);
45
Py_CLEAR(self->restype);
49
PyTypeObject CThunk_Type = {
50
PyVarObject_HEAD_INIT(NULL, 0)
51
"_ctypes.CThunkObject",
52
sizeof(CThunkObject), /* tp_basicsize */
53
sizeof(ffi_type), /* tp_itemsize */
54
CThunkObject_dealloc, /* tp_dealloc */
61
0, /* tp_as_sequence */
62
0, /* tp_as_mapping */
69
Py_TPFLAGS_DEFAULT, /* tp_flags */
70
"CThunkObject", /* tp_doc */
71
CThunkObject_traverse, /* tp_traverse */
72
CThunkObject_clear, /* tp_clear */
73
0, /* tp_richcompare */
74
0, /* tp_weaklistoffset */
81
/**************************************************************/
84
PrintError(char *msg, ...)
87
PyObject *f = PySys_GetObject("stderr");
90
va_start(marker, msg);
91
vsnprintf(buf, sizeof(buf), msg, marker);
94
PyFile_WriteString(buf, f);
99
/* after code that pyrex generates */
100
void _AddTraceback(char *funcname, char *filename, int lineno)
102
PyObject *py_srcfile = 0;
103
PyObject *py_funcname = 0;
104
PyObject *py_globals = 0;
105
PyObject *empty_tuple = 0;
106
PyObject *empty_string = 0;
107
PyCodeObject *py_code = 0;
108
PyFrameObject *py_frame = 0;
110
py_srcfile = PyString_FromString(filename);
111
if (!py_srcfile) goto bad;
112
py_funcname = PyString_FromString(funcname);
113
if (!py_funcname) goto bad;
114
py_globals = PyDict_New();
115
if (!py_globals) goto bad;
116
empty_tuple = PyTuple_New(0);
117
if (!empty_tuple) goto bad;
118
empty_string = PyString_FromString("");
119
if (!empty_string) goto bad;
120
py_code = PyCode_New(
123
0, /*int stacksize,*/
125
empty_string, /*PyObject *code,*/
126
empty_tuple, /*PyObject *consts,*/
127
empty_tuple, /*PyObject *names,*/
128
empty_tuple, /*PyObject *varnames,*/
129
empty_tuple, /*PyObject *freevars,*/
130
empty_tuple, /*PyObject *cellvars,*/
131
py_srcfile, /*PyObject *filename,*/
132
py_funcname, /*PyObject *name,*/
133
lineno, /*int firstlineno,*/
134
empty_string /*PyObject *lnotab*/
136
if (!py_code) goto bad;
137
py_frame = PyFrame_New(
138
PyThreadState_Get(), /*PyThreadState *tstate,*/
139
py_code, /*PyCodeObject *code,*/
140
py_globals, /*PyObject *globals,*/
141
0 /*PyObject *locals*/
143
if (!py_frame) goto bad;
144
py_frame->f_lineno = lineno;
145
PyTraceBack_Here(py_frame);
147
Py_XDECREF(py_globals);
148
Py_XDECREF(py_srcfile);
149
Py_XDECREF(py_funcname);
150
Py_XDECREF(empty_tuple);
151
Py_XDECREF(empty_string);
153
Py_XDECREF(py_frame);
158
* We must call AddRef() on non-NULL COM pointers we receive as arguments
159
* to callback functions - these functions are COM method implementations.
160
* The Python instances we create have a __del__ method which calls Release().
162
* The presence of a class attribute named '_needs_com_addref_' triggers this
163
* behaviour. It would also be possible to call the AddRef() Python method,
164
* after checking for PyObject_IsTrue(), but this would probably be somewhat
168
TryAddRef(StgDictObject *dict, CDataObject *obj)
172
if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
175
punk = *(IUnknown **)obj->b_ptr;
177
punk->lpVtbl->AddRef(punk);
182
/******************************************************************************
184
* Call the python object with all arguments
187
static void _CallPythonObject(void *mem,
191
PyObject *converters,
197
PyObject *arglist = NULL;
199
PyObject *error_object = NULL;
202
PyGILState_STATE state = PyGILState_Ensure();
205
nArgs = PySequence_Length(converters);
206
/* Hm. What to return in case of error?
207
For COM, 0xFFFFFFFF seems better than 0.
210
PrintError("BUG: PySequence_Length");
214
arglist = PyTuple_New(nArgs);
216
PrintError("PyTuple_New()");
219
for (i = 0; i < nArgs; ++i) {
220
/* Note: new reference! */
221
PyObject *cnv = PySequence_GetItem(converters, i);
224
dict = PyType_stgdict(cnv);
226
PrintError("Getting argument converter %d\n", i);
230
if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
231
PyObject *v = dict->getfunc(*pArgs, dict->size);
233
PrintError("create argument %d:\n", i);
237
PyTuple_SET_ITEM(arglist, i, v);
239
We have the problem that c_byte or c_short have dict->size of
240
1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
241
BTW, the same problem occurrs when they are pushed as parameters
244
/* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
245
CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
247
PrintError("create argument %d:\n", i);
251
if (!CDataObject_Check(obj)) {
254
PrintError("unexpected result of create argument %d:\n", i);
257
memcpy(obj->b_ptr, *pArgs, dict->size);
258
PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
260
TryAddRef(dict, obj);
263
PyErr_SetString(PyExc_TypeError,
264
"cannot build parameter");
265
PrintError("Parsing argument %d\n", i);
270
/* XXX error handling! */
274
#define CHECK(what, x) \
275
if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
277
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
278
error_object = get_error_object(&space);
279
if (error_object == NULL)
281
if (flags & FUNCFLAG_USE_ERRNO) {
287
if (flags & FUNCFLAG_USE_LASTERROR) {
289
space[1] = GetLastError();
295
result = PyObject_CallObject(callable, arglist);
296
CHECK("'calling callback function'", result);
299
if (flags & FUNCFLAG_USE_LASTERROR) {
301
space[1] = GetLastError();
305
if (flags & FUNCFLAG_USE_ERRNO) {
310
Py_XDECREF(error_object);
312
if ((restype != &ffi_type_void) && result) {
315
#ifdef WORDS_BIGENDIAN
316
/* See the corresponding code in callproc.c, around line 961 */
317
if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
318
mem = (char *)mem + sizeof(ffi_arg) - restype->size;
320
keep = setfunc(mem, result, 0);
321
CHECK("'converting callback result'", keep);
322
/* keep is an object we have to keep alive so that the result
323
stays valid. If there is no such object, the setfunc will
324
have returned Py_None.
326
If there is such an object, we have no choice than to keep
327
it alive forever - but a refcount and/or memory leak will
328
be the result. EXCEPT when restype is py_object - Python
329
itself knows how to manage the refcount of these objects.
331
if (keep == NULL) /* Could not convert callback result. */
332
PyErr_WriteUnraisable(callable);
333
else if (keep == Py_None) /* Nothing to keep */
335
else if (setfunc != getentry("O")->setfunc) {
336
if (-1 == PyErr_Warn(PyExc_RuntimeWarning,
337
"memory leak in callback function."))
338
PyErr_WriteUnraisable(callable);
345
PyGILState_Release(state);
349
static void closure_fcn(ffi_cif *cif,
354
CThunkObject *p = (CThunkObject *)userdata;
356
_CallPythonObject(resp,
365
static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
370
p = PyObject_NewVar(CThunkObject, &CThunk_Type, nArgs);
377
memset(&p->cif, 0, sizeof(p->cif));
378
p->converters = NULL;
381
p->ffi_restype = NULL;
383
for (i = 0; i < nArgs + 1; ++i)
388
CThunkObject *AllocFunctionCallback(PyObject *callable,
389
PyObject *converters,
398
nArgs = PySequence_Size(converters);
399
p = CThunkObject_new(nArgs);
403
assert(CThunk_CheckExact(p));
405
p->pcl = MallocClosure();
406
if (p->pcl == NULL) {
412
for (i = 0; i < nArgs; ++i) {
413
PyObject *cnv = PySequence_GetItem(converters, i);
416
p->atypes[i] = GetType(cnv);
422
p->restype = restype;
423
if (restype == Py_None) {
425
p->ffi_restype = &ffi_type_void;
427
StgDictObject *dict = PyType_stgdict(restype);
428
if (dict == NULL || dict->setfunc == NULL) {
429
PyErr_SetString(PyExc_TypeError,
430
"invalid result type for callback function");
433
p->setfunc = dict->setfunc;
434
p->ffi_restype = &dict->ffi_type_pointer;
437
cc = FFI_DEFAULT_ABI;
438
#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
439
if ((flags & FUNCFLAG_CDECL) == 0)
442
result = ffi_prep_cif(&p->cif, cc,
443
Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
446
if (result != FFI_OK) {
447
PyErr_Format(PyExc_RuntimeError,
448
"ffi_prep_cif failed with %d", result);
451
result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
452
if (result != FFI_OK) {
453
PyErr_Format(PyExc_RuntimeError,
454
"ffi_prep_closure failed with %d", result);
458
Py_INCREF(converters);
459
p->converters = converters;
461
p->callable = callable;
469
/****************************************************************************
471
* callback objects: initialization
474
void init_callbacks_in_module(PyObject *m)
476
if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
482
static void LoadPython(void)
484
if (!Py_IsInitialized()) {
486
PyEval_InitThreads();
492
/******************************************************************/
494
long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
496
PyObject *mod, *func, *result;
498
static PyObject *context;
501
context = PyString_InternFromString("_ctypes.DllGetClassObject");
503
mod = PyImport_ImportModuleNoBlock("ctypes");
505
PyErr_WriteUnraisable(context ? context : Py_None);
506
/* There has been a warning before about this already */
510
func = PyObject_GetAttrString(mod, "DllGetClassObject");
513
PyErr_WriteUnraisable(context ? context : Py_None);
518
PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid);
519
PyObject *py_riid = PyLong_FromVoidPtr((void *)riid);
520
PyObject *py_ppv = PyLong_FromVoidPtr(ppv);
521
if (!py_rclsid || !py_riid || !py_ppv) {
522
Py_XDECREF(py_rclsid);
526
PyErr_WriteUnraisable(context ? context : Py_None);
529
result = PyObject_CallFunctionObjArgs(func,
534
Py_DECREF(py_rclsid);
540
PyErr_WriteUnraisable(context ? context : Py_None);
544
retval = PyInt_AsLong(result);
545
if (PyErr_Occurred()) {
546
PyErr_WriteUnraisable(context ? context : Py_None);
553
STDAPI DllGetClassObject(REFCLSID rclsid,
559
PyGILState_STATE state;
564
state = PyGILState_Ensure();
566
result = Call_GetClassObject(rclsid, riid, ppv);
568
PyGILState_Release(state);
573
long Call_CanUnloadNow(void)
575
PyObject *mod, *func, *result;
577
static PyObject *context;
580
context = PyString_InternFromString("_ctypes.DllCanUnloadNow");
582
mod = PyImport_ImportModuleNoBlock("ctypes");
584
/* OutputDebugString("Could not import ctypes"); */
585
/* We assume that this error can only occur when shutting
586
down, so we silently ignore it */
590
/* Other errors cannot be raised, but are printed to stderr */
591
func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
594
PyErr_WriteUnraisable(context ? context : Py_None);
598
result = PyObject_CallFunction(func, NULL);
601
PyErr_WriteUnraisable(context ? context : Py_None);
605
retval = PyInt_AsLong(result);
606
if (PyErr_Occurred()) {
607
PyErr_WriteUnraisable(context ? context : Py_None);
615
DllRegisterServer and DllUnregisterServer still missing
618
STDAPI DllCanUnloadNow(void)
622
PyGILState_STATE state = PyGILState_Ensure();
624
result = Call_CanUnloadNow();
626
PyGILState_Release(state);
631
#ifndef Py_NO_ENABLE_SHARED
632
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
635
case DLL_PROCESS_ATTACH:
636
DisableThreadLibraryCalls(hinstDLL);
647
compile-command: "cd .. && python setup.py -q build_ext"