Issue #5768: Change to Unicode output logic and test case for same.
[python.git] / Modules / _ctypes / callbacks.c
blobea43c68bc6c4f6062f57a9297e22e8c96e3578df
1 /*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
5 #include "Python.h"
6 #include "compile.h" /* required only for 2.3, as it seems */
7 #include "frameobject.h"
9 #include <ffi.h>
10 #ifdef MS_WIN32
11 #include <windows.h>
12 #endif
13 #include "ctypes.h"
15 /**************************************************************/
17 static void
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);
24 if (self->pcl)
25 FreeClosure(self->pcl);
26 PyObject_Del(self);
29 static int
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);
36 return 0;
39 static int
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);
46 return 0;
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 */
55 0, /* tp_print */
56 0, /* tp_getattr */
57 0, /* tp_setattr */
58 0, /* tp_compare */
59 0, /* tp_repr */
60 0, /* tp_as_number */
61 0, /* tp_as_sequence */
62 0, /* tp_as_mapping */
63 0, /* tp_hash */
64 0, /* tp_call */
65 0, /* tp_str */
66 0, /* tp_getattro */
67 0, /* tp_setattro */
68 0, /* tp_as_buffer */
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 */
75 0, /* tp_iter */
76 0, /* tp_iternext */
77 0, /* tp_methods */
78 0, /* tp_members */
81 /**************************************************************/
83 static void
84 PrintError(char *msg, ...)
86 char buf[512];
87 PyObject *f = PySys_GetObject("stderr");
88 va_list marker;
90 va_start(marker, msg);
91 vsnprintf(buf, sizeof(buf), msg, marker);
92 va_end(marker);
93 if (f)
94 PyFile_WriteString(buf, f);
95 PyErr_Print();
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(
121 0, /*int argcount,*/
122 0, /*int nlocals,*/
123 0, /*int stacksize,*/
124 0, /*int flags,*/
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);
146 bad:
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);
152 Py_XDECREF(py_code);
153 Py_XDECREF(py_frame);
156 #ifdef MS_WIN32
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
165 * slower.
167 static void
168 TryAddRef(StgDictObject *dict, CDataObject *obj)
170 IUnknown *punk;
172 if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
173 return;
175 punk = *(IUnknown **)obj->b_ptr;
176 if (punk)
177 punk->lpVtbl->AddRef(punk);
178 return;
180 #endif
182 /******************************************************************************
184 * Call the python object with all arguments
187 static void _CallPythonObject(void *mem,
188 ffi_type *restype,
189 SETFUNC setfunc,
190 PyObject *callable,
191 PyObject *converters,
192 int flags,
193 void **pArgs)
195 Py_ssize_t i;
196 PyObject *result;
197 PyObject *arglist = NULL;
198 Py_ssize_t nArgs;
199 PyObject *error_object = NULL;
200 int *space;
201 #ifdef WITH_THREAD
202 PyGILState_STATE state = PyGILState_Ensure();
203 #endif
205 nArgs = PySequence_Length(converters);
206 /* Hm. What to return in case of error?
207 For COM, 0xFFFFFFFF seems better than 0.
209 if (nArgs < 0) {
210 PrintError("BUG: PySequence_Length");
211 goto Done;
214 arglist = PyTuple_New(nArgs);
215 if (!arglist) {
216 PrintError("PyTuple_New()");
217 goto Done;
219 for (i = 0; i < nArgs; ++i) {
220 /* Note: new reference! */
221 PyObject *cnv = PySequence_GetItem(converters, i);
222 StgDictObject *dict;
223 if (cnv)
224 dict = PyType_stgdict(cnv);
225 else {
226 PrintError("Getting argument converter %d\n", i);
227 goto Done;
230 if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
231 PyObject *v = dict->getfunc(*pArgs, dict->size);
232 if (!v) {
233 PrintError("create argument %d:\n", i);
234 Py_DECREF(cnv);
235 goto Done;
237 PyTuple_SET_ITEM(arglist, i, v);
238 /* XXX XXX XX
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
243 } else if (dict) {
244 /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
245 CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
246 if (!obj) {
247 PrintError("create argument %d:\n", i);
248 Py_DECREF(cnv);
249 goto Done;
251 if (!CDataObject_Check(obj)) {
252 Py_DECREF(obj);
253 Py_DECREF(cnv);
254 PrintError("unexpected result of create argument %d:\n", i);
255 goto Done;
257 memcpy(obj->b_ptr, *pArgs, dict->size);
258 PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
259 #ifdef MS_WIN32
260 TryAddRef(dict, obj);
261 #endif
262 } else {
263 PyErr_SetString(PyExc_TypeError,
264 "cannot build parameter");
265 PrintError("Parsing argument %d\n", i);
266 Py_DECREF(cnv);
267 goto Done;
269 Py_DECREF(cnv);
270 /* XXX error handling! */
271 pArgs++;
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)
280 goto Done;
281 if (flags & FUNCFLAG_USE_ERRNO) {
282 int temp = space[0];
283 space[0] = errno;
284 errno = temp;
286 #ifdef MS_WIN32
287 if (flags & FUNCFLAG_USE_LASTERROR) {
288 int temp = space[1];
289 space[1] = GetLastError();
290 SetLastError(temp);
292 #endif
295 result = PyObject_CallObject(callable, arglist);
296 CHECK("'calling callback function'", result);
298 #ifdef MS_WIN32
299 if (flags & FUNCFLAG_USE_LASTERROR) {
300 int temp = space[1];
301 space[1] = GetLastError();
302 SetLastError(temp);
304 #endif
305 if (flags & FUNCFLAG_USE_ERRNO) {
306 int temp = space[0];
307 space[0] = errno;
308 errno = temp;
310 Py_XDECREF(error_object);
312 if ((restype != &ffi_type_void) && result) {
313 PyObject *keep;
314 assert(setfunc);
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;
319 #endif
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 */
334 Py_DECREF(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);
341 Py_XDECREF(result);
342 Done:
343 Py_XDECREF(arglist);
344 #ifdef WITH_THREAD
345 PyGILState_Release(state);
346 #endif
349 static void closure_fcn(ffi_cif *cif,
350 void *resp,
351 void **args,
352 void *userdata)
354 CThunkObject *p = (CThunkObject *)userdata;
356 _CallPythonObject(resp,
357 p->ffi_restype,
358 p->setfunc,
359 p->callable,
360 p->converters,
361 p->flags,
362 args);
365 static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
367 CThunkObject *p;
368 int i;
370 p = PyObject_NewVar(CThunkObject, &CThunk_Type, nArgs);
371 if (p == NULL) {
372 PyErr_NoMemory();
373 return NULL;
376 p->pcl = NULL;
377 memset(&p->cif, 0, sizeof(p->cif));
378 p->converters = NULL;
379 p->callable = NULL;
380 p->setfunc = NULL;
381 p->ffi_restype = NULL;
383 for (i = 0; i < nArgs + 1; ++i)
384 p->atypes[i] = NULL;
385 return p;
388 CThunkObject *AllocFunctionCallback(PyObject *callable,
389 PyObject *converters,
390 PyObject *restype,
391 int flags)
393 int result;
394 CThunkObject *p;
395 Py_ssize_t nArgs, i;
396 ffi_abi cc;
398 nArgs = PySequence_Size(converters);
399 p = CThunkObject_new(nArgs);
400 if (p == NULL)
401 return NULL;
403 assert(CThunk_CheckExact(p));
405 p->pcl = MallocClosure();
406 if (p->pcl == NULL) {
407 PyErr_NoMemory();
408 goto error;
411 p->flags = flags;
412 for (i = 0; i < nArgs; ++i) {
413 PyObject *cnv = PySequence_GetItem(converters, i);
414 if (cnv == NULL)
415 goto error;
416 p->atypes[i] = GetType(cnv);
417 Py_DECREF(cnv);
419 p->atypes[i] = NULL;
421 Py_INCREF(restype);
422 p->restype = restype;
423 if (restype == Py_None) {
424 p->setfunc = NULL;
425 p->ffi_restype = &ffi_type_void;
426 } else {
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");
431 goto error;
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)
440 cc = FFI_STDCALL;
441 #endif
442 result = ffi_prep_cif(&p->cif, cc,
443 Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
444 GetType(restype),
445 &p->atypes[0]);
446 if (result != FFI_OK) {
447 PyErr_Format(PyExc_RuntimeError,
448 "ffi_prep_cif failed with %d", result);
449 goto error;
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);
455 goto error;
458 Py_INCREF(converters);
459 p->converters = converters;
460 Py_INCREF(callable);
461 p->callable = callable;
462 return p;
464 error:
465 Py_XDECREF(p);
466 return NULL;
469 #ifdef MS_WIN32
471 static void LoadPython(void)
473 if (!Py_IsInitialized()) {
474 #ifdef WITH_THREAD
475 PyEval_InitThreads();
476 #endif
477 Py_Initialize();
481 /******************************************************************/
483 long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
485 PyObject *mod, *func, *result;
486 long retval;
487 static PyObject *context;
489 if (context == NULL)
490 context = PyString_InternFromString("_ctypes.DllGetClassObject");
492 mod = PyImport_ImportModuleNoBlock("ctypes");
493 if (!mod) {
494 PyErr_WriteUnraisable(context ? context : Py_None);
495 /* There has been a warning before about this already */
496 return E_FAIL;
499 func = PyObject_GetAttrString(mod, "DllGetClassObject");
500 Py_DECREF(mod);
501 if (!func) {
502 PyErr_WriteUnraisable(context ? context : Py_None);
503 return E_FAIL;
507 PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid);
508 PyObject *py_riid = PyLong_FromVoidPtr((void *)riid);
509 PyObject *py_ppv = PyLong_FromVoidPtr(ppv);
510 if (!py_rclsid || !py_riid || !py_ppv) {
511 Py_XDECREF(py_rclsid);
512 Py_XDECREF(py_riid);
513 Py_XDECREF(py_ppv);
514 Py_DECREF(func);
515 PyErr_WriteUnraisable(context ? context : Py_None);
516 return E_FAIL;
518 result = PyObject_CallFunctionObjArgs(func,
519 py_rclsid,
520 py_riid,
521 py_ppv,
522 NULL);
523 Py_DECREF(py_rclsid);
524 Py_DECREF(py_riid);
525 Py_DECREF(py_ppv);
527 Py_DECREF(func);
528 if (!result) {
529 PyErr_WriteUnraisable(context ? context : Py_None);
530 return E_FAIL;
533 retval = PyInt_AsLong(result);
534 if (PyErr_Occurred()) {
535 PyErr_WriteUnraisable(context ? context : Py_None);
536 retval = E_FAIL;
538 Py_DECREF(result);
539 return retval;
542 STDAPI DllGetClassObject(REFCLSID rclsid,
543 REFIID riid,
544 LPVOID *ppv)
546 long result;
547 #ifdef WITH_THREAD
548 PyGILState_STATE state;
549 #endif
551 LoadPython();
552 #ifdef WITH_THREAD
553 state = PyGILState_Ensure();
554 #endif
555 result = Call_GetClassObject(rclsid, riid, ppv);
556 #ifdef WITH_THREAD
557 PyGILState_Release(state);
558 #endif
559 return result;
562 long Call_CanUnloadNow(void)
564 PyObject *mod, *func, *result;
565 long retval;
566 static PyObject *context;
568 if (context == NULL)
569 context = PyString_InternFromString("_ctypes.DllCanUnloadNow");
571 mod = PyImport_ImportModuleNoBlock("ctypes");
572 if (!mod) {
573 /* OutputDebugString("Could not import ctypes"); */
574 /* We assume that this error can only occur when shutting
575 down, so we silently ignore it */
576 PyErr_Clear();
577 return E_FAIL;
579 /* Other errors cannot be raised, but are printed to stderr */
580 func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
581 Py_DECREF(mod);
582 if (!func) {
583 PyErr_WriteUnraisable(context ? context : Py_None);
584 return E_FAIL;
587 result = PyObject_CallFunction(func, NULL);
588 Py_DECREF(func);
589 if (!result) {
590 PyErr_WriteUnraisable(context ? context : Py_None);
591 return E_FAIL;
594 retval = PyInt_AsLong(result);
595 if (PyErr_Occurred()) {
596 PyErr_WriteUnraisable(context ? context : Py_None);
597 retval = E_FAIL;
599 Py_DECREF(result);
600 return retval;
604 DllRegisterServer and DllUnregisterServer still missing
607 STDAPI DllCanUnloadNow(void)
609 long result;
610 #ifdef WITH_THREAD
611 PyGILState_STATE state = PyGILState_Ensure();
612 #endif
613 result = Call_CanUnloadNow();
614 #ifdef WITH_THREAD
615 PyGILState_Release(state);
616 #endif
617 return result;
620 #ifndef Py_NO_ENABLE_SHARED
621 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
623 switch(fdwReason) {
624 case DLL_PROCESS_ATTACH:
625 DisableThreadLibraryCalls(hinstDLL);
626 break;
628 return TRUE;
630 #endif
632 #endif
635 Local Variables:
636 compile-command: "cd .. && python setup.py -q build_ext"
637 End: