2
#include "frameobject.h"
10
/**************************************************************/
13
CThunkObject_dealloc(PyObject *_self)
15
CThunkObject *self = (CThunkObject *)_self;
16
Py_XDECREF(self->converters);
17
Py_XDECREF(self->callable);
18
Py_XDECREF(self->restype);
20
FreeClosure(self->pcl);
25
CThunkObject_traverse(PyObject *_self, visitproc visit, void *arg)
27
CThunkObject *self = (CThunkObject *)_self;
28
Py_VISIT(self->converters);
29
Py_VISIT(self->callable);
30
Py_VISIT(self->restype);
35
CThunkObject_clear(PyObject *_self)
37
CThunkObject *self = (CThunkObject *)_self;
38
Py_CLEAR(self->converters);
39
Py_CLEAR(self->callable);
40
Py_CLEAR(self->restype);
44
PyTypeObject CThunk_Type = {
45
PyVarObject_HEAD_INIT(NULL, 0)
46
"_ctypes.CThunkObject",
47
sizeof(CThunkObject), /* tp_basicsize */
48
sizeof(ffi_type), /* tp_itemsize */
49
CThunkObject_dealloc, /* tp_dealloc */
56
0, /* tp_as_sequence */
57
0, /* tp_as_mapping */
64
Py_TPFLAGS_DEFAULT, /* tp_flags */
65
"CThunkObject", /* tp_doc */
66
CThunkObject_traverse, /* tp_traverse */
67
CThunkObject_clear, /* tp_clear */
68
0, /* tp_richcompare */
69
0, /* tp_weaklistoffset */
76
/**************************************************************/
79
PrintError(char *msg, ...)
82
PyObject *f = PySys_GetObject("stderr");
85
va_start(marker, msg);
86
vsnprintf(buf, sizeof(buf), msg, marker);
88
if (f != NULL && f != Py_None)
89
PyFile_WriteString(buf, f);
94
/* after code that pyrex generates */
95
void _AddTraceback(char *funcname, char *filename, int lineno)
97
PyObject *py_srcfile = 0;
98
PyObject *py_funcname = 0;
99
PyObject *py_globals = 0;
100
PyObject *empty_tuple = 0;
101
PyObject *empty_string = 0;
102
PyCodeObject *py_code = 0;
103
PyFrameObject *py_frame = 0;
105
py_srcfile = PyUnicode_DecodeFSDefault(filename);
106
if (!py_srcfile) goto bad;
107
py_funcname = PyUnicode_FromString(funcname);
108
if (!py_funcname) goto bad;
109
py_globals = PyDict_New();
110
if (!py_globals) goto bad;
111
empty_tuple = PyTuple_New(0);
112
if (!empty_tuple) goto bad;
113
empty_string = PyBytes_FromString("");
114
if (!empty_string) goto bad;
115
py_code = PyCode_New(
117
0, /*int kwonlyargcount,*/
119
0, /*int stacksize,*/
121
empty_string, /*PyObject *code,*/
122
empty_tuple, /*PyObject *consts,*/
123
empty_tuple, /*PyObject *names,*/
124
empty_tuple, /*PyObject *varnames,*/
125
empty_tuple, /*PyObject *freevars,*/
126
empty_tuple, /*PyObject *cellvars,*/
127
py_srcfile, /*PyObject *filename,*/
128
py_funcname, /*PyObject *name,*/
129
lineno, /*int firstlineno,*/
130
empty_string /*PyObject *lnotab*/
132
if (!py_code) goto bad;
133
py_frame = PyFrame_New(
134
PyThreadState_Get(), /*PyThreadState *tstate,*/
135
py_code, /*PyCodeObject *code,*/
136
py_globals, /*PyObject *globals,*/
137
0 /*PyObject *locals*/
139
if (!py_frame) goto bad;
140
py_frame->f_lineno = lineno;
141
PyTraceBack_Here(py_frame);
143
Py_XDECREF(py_globals);
144
Py_XDECREF(py_srcfile);
145
Py_XDECREF(py_funcname);
146
Py_XDECREF(empty_tuple);
147
Py_XDECREF(empty_string);
149
Py_XDECREF(py_frame);
154
* We must call AddRef() on non-NULL COM pointers we receive as arguments
155
* to callback functions - these functions are COM method implementations.
156
* The Python instances we create have a __del__ method which calls Release().
158
* The presence of a class attribute named '_needs_com_addref_' triggers this
159
* behaviour. It would also be possible to call the AddRef() Python method,
160
* after checking for PyObject_IsTrue(), but this would probably be somewhat
164
TryAddRef(StgDictObject *dict, CDataObject *obj)
168
if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
171
punk = *(IUnknown **)obj->b_ptr;
173
punk->lpVtbl->AddRef(punk);
178
/******************************************************************************
180
* Call the python object with all arguments
183
static void _CallPythonObject(void *mem,
187
PyObject *converters,
193
PyObject *arglist = NULL;
195
PyObject *error_object = NULL;
198
PyGILState_STATE state = PyGILState_Ensure();
201
nArgs = PySequence_Length(converters);
202
/* Hm. What to return in case of error?
203
For COM, 0xFFFFFFFF seems better than 0.
206
PrintError("BUG: PySequence_Length");
210
arglist = PyTuple_New(nArgs);
212
PrintError("PyTuple_New()");
215
for (i = 0; i < nArgs; ++i) {
216
/* Note: new reference! */
217
PyObject *cnv = PySequence_GetItem(converters, i);
220
dict = PyType_stgdict(cnv);
222
PrintError("Getting argument converter %d\n", i);
226
if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
227
PyObject *v = dict->getfunc(*pArgs, dict->size);
229
PrintError("create argument %d:\n", i);
233
PyTuple_SET_ITEM(arglist, i, v);
235
We have the problem that c_byte or c_short have dict->size of
236
1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
237
BTW, the same problem occurrs when they are pushed as parameters
240
/* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
241
CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
243
PrintError("create argument %d:\n", i);
247
if (!CDataObject_Check(obj)) {
250
PrintError("unexpected result of create argument %d:\n", i);
253
memcpy(obj->b_ptr, *pArgs, dict->size);
254
PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
256
TryAddRef(dict, obj);
259
PyErr_SetString(PyExc_TypeError,
260
"cannot build parameter");
261
PrintError("Parsing argument %d\n", i);
266
/* XXX error handling! */
270
#define CHECK(what, x) \
271
if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
273
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
274
error_object = get_error_object(&space);
275
if (error_object == NULL)
277
if (flags & FUNCFLAG_USE_ERRNO) {
283
if (flags & FUNCFLAG_USE_LASTERROR) {
285
space[1] = GetLastError();
291
result = PyObject_CallObject(callable, arglist);
292
CHECK("'calling callback function'", result);
295
if (flags & FUNCFLAG_USE_LASTERROR) {
297
space[1] = GetLastError();
301
if (flags & FUNCFLAG_USE_ERRNO) {
306
Py_XDECREF(error_object);
308
if ((restype != &ffi_type_void) && result) {
311
#ifdef WORDS_BIGENDIAN
312
/* See the corresponding code in callproc.c, around line 961 */
313
if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
314
mem = (char *)mem + sizeof(ffi_arg) - restype->size;
316
keep = setfunc(mem, result, 0);
317
CHECK("'converting callback result'", keep);
318
/* keep is an object we have to keep alive so that the result
319
stays valid. If there is no such object, the setfunc will
320
have returned Py_None.
322
If there is such an object, we have no choice than to keep
323
it alive forever - but a refcount and/or memory leak will
324
be the result. EXCEPT when restype is py_object - Python
325
itself knows how to manage the refcount of these objects.
327
if (keep == NULL) /* Could not convert callback result. */
328
PyErr_WriteUnraisable(callable);
329
else if (keep == Py_None) /* Nothing to keep */
331
else if (setfunc != getentry("O")->setfunc) {
332
if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning,
333
"memory leak in callback function.",
335
PyErr_WriteUnraisable(callable);
342
PyGILState_Release(state);
346
static void closure_fcn(ffi_cif *cif,
351
CThunkObject *p = (CThunkObject *)userdata;
353
_CallPythonObject(resp,
362
static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
367
p = PyObject_NewVar(CThunkObject, &CThunk_Type, nArgs);
374
memset(&p->cif, 0, sizeof(p->cif));
375
p->converters = NULL;
378
p->ffi_restype = NULL;
380
for (i = 0; i < nArgs + 1; ++i)
385
CThunkObject *AllocFunctionCallback(PyObject *callable,
386
PyObject *converters,
395
nArgs = PySequence_Size(converters);
396
p = CThunkObject_new(nArgs);
400
assert(CThunk_CheckExact((PyObject *)p));
402
p->pcl = MallocClosure();
403
if (p->pcl == NULL) {
409
for (i = 0; i < nArgs; ++i) {
410
PyObject *cnv = PySequence_GetItem(converters, i);
413
p->atypes[i] = GetType(cnv);
419
p->restype = restype;
420
if (restype == Py_None) {
422
p->ffi_restype = &ffi_type_void;
424
StgDictObject *dict = PyType_stgdict(restype);
425
if (dict == NULL || dict->setfunc == NULL) {
426
PyErr_SetString(PyExc_TypeError,
427
"invalid result type for callback function");
430
p->setfunc = dict->setfunc;
431
p->ffi_restype = &dict->ffi_type_pointer;
434
cc = FFI_DEFAULT_ABI;
435
#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
436
if ((flags & FUNCFLAG_CDECL) == 0)
439
result = ffi_prep_cif(&p->cif, cc,
440
Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
443
if (result != FFI_OK) {
444
PyErr_Format(PyExc_RuntimeError,
445
"ffi_prep_cif failed with %d", result);
448
result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
449
if (result != FFI_OK) {
450
PyErr_Format(PyExc_RuntimeError,
451
"ffi_prep_closure failed with %d", result);
455
Py_INCREF(converters);
456
p->converters = converters;
458
p->callable = callable;
466
/****************************************************************************
468
* callback objects: initialization
471
void init_callbacks_in_module(PyObject *m)
473
if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
479
static void LoadPython(void)
481
if (!Py_IsInitialized()) {
483
PyEval_InitThreads();
489
/******************************************************************/
491
long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
493
PyObject *mod, *func, *result;
495
static PyObject *context;
498
context = PyUnicode_InternFromString("_ctypes.DllGetClassObject");
500
mod = PyImport_ImportModuleNoBlock("ctypes");
502
PyErr_WriteUnraisable(context ? context : Py_None);
503
/* There has been a warning before about this already */
507
func = PyObject_GetAttrString(mod, "DllGetClassObject");
510
PyErr_WriteUnraisable(context ? context : Py_None);
515
PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid);
516
PyObject *py_riid = PyLong_FromVoidPtr((void *)riid);
517
PyObject *py_ppv = PyLong_FromVoidPtr(ppv);
518
if (!py_rclsid || !py_riid || !py_ppv) {
519
Py_XDECREF(py_rclsid);
523
PyErr_WriteUnraisable(context ? context : Py_None);
526
result = PyObject_CallFunctionObjArgs(func,
531
Py_DECREF(py_rclsid);
537
PyErr_WriteUnraisable(context ? context : Py_None);
541
retval = PyLong_AsLong(result);
542
if (PyErr_Occurred()) {
543
PyErr_WriteUnraisable(context ? context : Py_None);
550
STDAPI DllGetClassObject(REFCLSID rclsid,
556
PyGILState_STATE state;
561
state = PyGILState_Ensure();
563
result = Call_GetClassObject(rclsid, riid, ppv);
565
PyGILState_Release(state);
570
long Call_CanUnloadNow(void)
572
PyObject *mod, *func, *result;
574
static PyObject *context;
577
context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow");
579
mod = PyImport_ImportModuleNoBlock("ctypes");
581
/* OutputDebugString("Could not import ctypes"); */
582
/* We assume that this error can only occur when shutting
583
down, so we silently ignore it */
587
/* Other errors cannot be raised, but are printed to stderr */
588
func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
591
PyErr_WriteUnraisable(context ? context : Py_None);
595
result = PyObject_CallFunction(func, NULL);
598
PyErr_WriteUnraisable(context ? context : Py_None);
602
retval = PyLong_AsLong(result);
603
if (PyErr_Occurred()) {
604
PyErr_WriteUnraisable(context ? context : Py_None);
612
DllRegisterServer and DllUnregisterServer still missing
615
STDAPI DllCanUnloadNow(void)
619
PyGILState_STATE state = PyGILState_Ensure();
621
result = Call_CanUnloadNow();
623
PyGILState_Release(state);
628
#ifndef Py_NO_ENABLE_SHARED
629
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
632
case DLL_PROCESS_ATTACH:
633
DisableThreadLibraryCalls(hinstDLL);
644
compile-command: "cd .. && python setup.py -q build_ext"