1#ifndef PyObjC_API_H 2#define PyObjC_API_H 3 4/* 5 * Use this in helper modules for the objc package, and in wrappers 6 * for functions that deal with objective-C objects/classes 7 * 8 * This header defines some utility wrappers for importing and using 9 * the core bridge. 10 * 11 * This is the *only* header file that should be used to access 12 * functionality in the core bridge. 13 * 14 * WARNING: this file is not part of the public interface of PyObjC and 15 * might change or be removed without warning or regard for backward 16 * compatibility. 17 */ 18 19#include "Python.h" 20#include <objc/objc.h> 21 22#import <Foundation/Foundation.h> 23 24#include "pyobjc-compat.h" 25 26 27 28 29 30#import <Foundation/NSException.h> 31 32struct PyObjC_WeakLink { 33 const char* name; 34 void (*func)(void); 35}; 36 37 38/* threading support */ 39#ifdef NO_OBJC2_RUNTIME 40#define PyObjC_DURING \ 41 Py_BEGIN_ALLOW_THREADS \ 42 NS_DURING 43 44#define PyObjC_HANDLER NS_HANDLER 45 46#define PyObjC_ENDHANDLER \ 47 NS_ENDHANDLER \ 48 Py_END_ALLOW_THREADS 49#else 50 51#define PyObjC_DURING \ 52 Py_BEGIN_ALLOW_THREADS \ 53 @try { 54 55#define PyObjC_HANDLER } @catch(volatile NSObject* _localException) { \ 56 NSException* localException __attribute__((__unused__))= (NSException*)_localException; 57 58#define PyObjC_ENDHANDLER \ 59 } \ 60 Py_END_ALLOW_THREADS 61 62#endif 63 64#define PyObjC_BEGIN_WITH_GIL \ 65 { \ 66 PyGILState_STATE _GILState; \ 67 _GILState = PyGILState_Ensure(); 68 69#define PyObjC_GIL_FORWARD_EXC() \ 70 do { \ 71 PyObjCErr_ToObjCWithGILState(&_GILState); \ 72 } while (0) 73 74 75#define PyObjC_GIL_RETURN(val) \ 76 do { \ 77 PyGILState_Release(_GILState); \ 78 return (val); \ 79 } while (0) 80 81#define PyObjC_GIL_RETURNVOID \ 82 do { \ 83 PyGILState_Release(_GILState); \ 84 return; \ 85 } while (0) 86 87 88#define PyObjC_END_WITH_GIL \ 89 PyGILState_Release(_GILState); \ 90 } 91 92 93 94#include <objc/objc-runtime.h> 95 96/* On 10.1 there are no defines for the OS version. */ 97#ifndef MAC_OS_X_VERSION_10_1 98#define MAC_OS_X_VERSION_10_1 1010 99#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_1 100 101#error "MAC_OS_X_VERSION_10_1 not defined. You aren't running 10.1 are you?" 102 103#endif 104 105#ifndef MAC_OS_X_VERSION_10_2 106#define MAC_OS_X_VERSION_10_2 1020 107#endif 108 109#ifndef MAC_OS_X_VERSION_10_3 110#define MAC_OS_X_VERSION_10_3 1030 111#endif 112 113#ifndef MAC_OS_X_VERSION_10_4 114#define MAC_OS_X_VERSION_10_4 1040 115#endif 116 117#ifndef MAC_OS_X_VERSION_10_5 118#define MAC_OS_X_VERSION_10_5 1050 119#endif 120 121/* Current API version, increase whenever: 122 * - Semantics of current functions change 123 * - Functions are removed 124 * Do not increase when adding a new function, the struct_len field 125 * can be used for detecting if a function has been added. 126 * 127 * HISTORY: 128 * - Version 2.2 adds PyObjCUnsupportedMethod_IMP 129 * and PyObjCUnsupportedMethod_Caller 130 * - Version 2.1 adds PyObjCPointerWrapper_Register 131 * - Version 2 adds an argument to PyObjC_InitSuper 132 * - Version 3 adds another argument to PyObjC_CallPython 133 * - Version 4 adds PyObjCErr_ToObjCGILState 134 * - Version 4.1 adds PyObjCRT_AlignOfType and PyObjCRT_SizeOfType 135 * (PyObjC_SizeOfType is now deprecated) 136 * - Version 4.2 adds PyObjCRT_SELName 137 * - Version 4.3 adds PyObjCRT_SimplifySignature 138 * - Version 4.4 adds PyObjC_FreeCArray, PyObjC_PythonToCArray and 139 * PyObjC_CArrayToPython 140 * - Version 5 modifies the signature for PyObjC_RegisterMethodMapping, 141 * PyObjC_RegisterSignatureMapping and PyObjCUnsupportedMethod_IMP, 142 * adds PyObjC_RegisterStructType and removes PyObjC_CallPython 143 * - Version 6 adds PyObjCIMP_Type, PyObjCIMP_GetIMP and PyObjCIMP_GetSelector 144 * - Version 7 adds PyObjCErr_AsExc, PyGILState_Ensure 145 * - Version 8 adds PyObjCObject_IsUninitialized, 146 removes PyObjCSelector_IsInitializer 147 * - Version 9 (???) 148 * - Version 10 changes the signature of PyObjCRT_SimplifySignature 149 * - Version 11 adds PyObjCObject_Convert, PyObjCSelector_Convert, 150 PyObjCClass_Convert, PyObjC_ConvertBOOL, and PyObjC_ConvertChar 151 * - Version 12 adds PyObjCObject_New 152 * - Version 13 adds PyObjCCreateOpaquePointerType 153 * - Version 14 adds PyObjCObject_NewTransient, PyObjCObject_ReleaseTransient 154 * - Version 15 changes the interface of PyObjCObject_New 155 * - Version 16 adds PyObjC_PerformWeaklinking 156 * - Version 17 introduces Py_ssize_t support 157 * - Version 18 introduces several API incompatibilities 158 * - Version 19 removes some old junk 159 */ 160#define PYOBJC_API_VERSION 19 161 162#define PYOBJC_API_NAME "__C_API__" 163 164/* 165 * Only add items to the end of this list! 166 */ 167typedef int (RegisterMethodMappingFunctionType)( 168 Class, 169 SEL, 170 PyObject *(*)(PyObject*, PyObject*, PyObject*), 171 void (*)(void*, void*, void**, void*)); 172 173struct pyobjc_api { 174 int api_version; /* API version */ 175 size_t struct_len; /* Length of this struct */ 176 PyTypeObject* class_type; /* PyObjCClass_Type */ 177 PyTypeObject* object_type; /* PyObjCObject_Type */ 178 PyTypeObject* select_type; /* PyObjCSelector_Type */ 179 180 /* PyObjC_RegisterMethodMapping */ 181 RegisterMethodMappingFunctionType *register_method_mapping; 182 183 /* PyObjC_RegisterSignatureMapping */ 184 int (*register_signature_mapping)( 185 char*, 186 PyObject *(*)(PyObject*, PyObject*, PyObject*), 187 void (*)(void*, void*, void**, void*)); 188 189 /* PyObjCObject_GetObject */ 190 id (*obj_get_object)(PyObject*); 191 192 /* PyObjCObject_ClearObject */ 193 void (*obj_clear_object)(PyObject*); 194 195 /* PyObjCClass_GetClass */ 196 Class (*cls_get_class)(PyObject*); 197 198 /* PyObjCClass_New */ 199 PyObject* (*cls_to_python)(Class cls); 200 201 /* PyObjC_PythonToId */ 202 id (*python_to_id)(PyObject*); 203 204 /* PyObjC_IdToPython */ 205 PyObject* (*id_to_python)(id); 206 207 /* PyObjCErr_FromObjC */ 208 void (*err_objc_to_python)(NSException*); 209 210 /* PyObjCErr_ToObjC */ 211 void (*err_python_to_objc)(void); 212 213 /* PyObjC_PythonToObjC */ 214 int (*py_to_objc)(const char*, PyObject*, void*); 215 216 /* PyObjC_ObjCToPython */ 217 PyObject* (*objc_to_py)(const char*, void*); 218 219 /* PyObjC_SizeOfType */ 220 Py_ssize_t (*sizeof_type)(const char*); 221 222 /* PyObjCSelector_GetClass */ 223 Class (*sel_get_class)(PyObject* sel); 224 225 /* PyObjCSelector_GetSelector */ 226 SEL (*sel_get_sel)(PyObject* sel); 227 228 /* PyObjC_InitSuper */ 229 void (*fill_super)(struct objc_super*, Class, id); 230 231 /* PyObjC_InitSuperCls */ 232 void (*fill_super_cls)(struct objc_super*, Class, Class); 233 234 /* PyObjCPointerWrapper_Register */ 235 int (*register_pointer_wrapper)( 236 const char*, PyObject* (*pythonify)(void*), 237 int (*depythonify)(PyObject*, void*) 238 ); 239 240 void (*unsupported_method_imp)(void*, void*, void**, void*); 241 PyObject* (*unsupported_method_caller)(PyObject*, PyObject*, PyObject*); 242 243 /* PyObjCErr_ToObjCWithGILState */ 244 void (*err_python_to_objc_gil)(PyGILState_STATE* state); 245 246 /* PyObjCRT_AlignOfType */ 247 Py_ssize_t (*alignof_type)(const char* typestr); 248 249 /* PyObjCRT_SELName */ 250 const char* (*selname)(SEL sel); 251 252 /* PyObjCRT_SimplifySignature */ 253 int (*simplify_sig)(char* signature, char* buf, size_t buflen); 254 255 /* PyObjC_FreeCArray */ 256 void (*free_c_array)(int,void*); 257 258 /* PyObjC_PythonToCArray */ 259 int (*py_to_c_array)(BOOL, BOOL, const char*, PyObject*, void**, Py_ssize_t*, PyObject**); 260 261 /* PyObjC_CArrayToPython */ 262 PyObject* (*c_array_to_py)(const char*, void*, Py_ssize_t); 263 264 /* PyObjC_RegisterStructType */ 265 PyObject* (*register_struct)(const char*, const char*, const char*, initproc, Py_ssize_t, const char**); 266 267 /* PyObjCIMP_Type */ 268 PyTypeObject* imp_type; 269 270 /* PyObjCIMP_GetIMP */ 271 IMP (*imp_get_imp)(PyObject*); 272 273 /* PyObjCIMP_GetSelector */ 274 SEL (*imp_get_sel)(PyObject*); 275 276 /* PyObjCErr_AsExc */ 277 NSException* (*err_python_to_nsexception)(void); 278 279 /* PyGILState_Ensure */ 280 PyGILState_STATE (*gilstate_ensure)(void); 281 282 /* PyObjCObject_IsUninitialized */ 283 int (*obj_is_uninitialized)(PyObject*); 284 285 /* PyObjCObject_New */ 286 PyObject* (*pyobjc_object_new)(id, int , int); 287 288 /* PyObjCCreateOpaquePointerType */ 289 PyObject* (*pointer_type_new)(const char*, const char*, const char*); 290 291 /* PyObject* PyObjCObject_NewTransient(id objc_object, int* cookie); */ 292 PyObject* (*newtransient)(id objc_object, int* cookie); 293 294 /* void PyObjCObject_ReleaseTransient(PyObject* proxy, int cookie); */ 295 void (*releasetransient)(PyObject* proxy, int cookie); 296 297 void (*doweaklink)(PyObject*, struct PyObjC_WeakLink*); 298 299 const char* (*removefields)(char*, const char*); 300 301 PyObject** pyobjc_null; 302 303 int (*dep_c_array_count)(const char* type, Py_ssize_t count, BOOL strict, PyObject* value, void* datum); 304 305 PyObject* (*varlistnew)(const char* tp, void* array); 306 307 int (*is_ascii_string)(PyObject* unicode_string, const char* ascii_string); 308 int (*is_ascii_prefix)(PyObject* unicode_string, const char* ascii_string, size_t n); 309 310 int (*pyobjcobject_convert)(PyObject*,void*); 311}; 312 313#ifndef PYOBJC_BUILD 314 315#ifndef PYOBJC_METHOD_STUB_IMPL 316static struct pyobjc_api* PyObjC_API; 317#endif /* PYOBJC_METHOD_STUB_IMPL */ 318 319#define PyObjC_is_ascii_string (PyObjC_API->is_ascii_string) 320#define PyObjC_is_ascii_prefix (PyObjC_API->is_ascii_prefix) 321 322#define PyObjCObject_Check(obj) PyObject_TypeCheck(obj, PyObjC_API->object_type) 323#define PyObjCClass_Check(obj) PyObject_TypeCheck(obj, PyObjC_API->class_type) 324#define PyObjCSelector_Check(obj) PyObject_TypeCheck(obj, PyObjC_API->select_type) 325#define PyObjCIMP_Check(obj) PyObject_TypeCheck(obj, PyObjC_API->imp_type) 326#define PyObjCObject_GetObject (PyObjC_API->obj_get_object) 327#define PyObjCObject_ClearObject (PyObjC_API->obj_clear_object) 328#define PyObjCClass_GetClass (PyObjC_API->cls_get_class) 329#define PyObjCClass_New (PyObjC_API->cls_to_python) 330#define PyObjCSelector_GetClass (PyObjC_API->sel_get_class) 331#define PyObjCSelector_GetSelector (PyObjC_API->sel_get_sel) 332#define PyObjC_PythonToId (PyObjC_API->python_to_id) 333#define PyObjC_IdToPython (PyObjC_API->id_to_python) 334#define PyObjCErr_FromObjC (PyObjC_API->err_objc_to_python) 335#define PyObjCErr_ToObjC (PyObjC_API->err_python_to_objc) 336#define PyObjCErr_ToObjCWithGILState (PyObjC_API->err_python_to_objc_gil) 337#define PyObjCErr_AsExc (PyObjC_API->err_python_to_nsexception) 338#define PyObjC_PythonToObjC (PyObjC_API->py_to_objc) 339#define PyObjC_ObjCToPython (PyObjC_API->objc_to_py) 340#define PyObjC_RegisterMethodMapping (PyObjC_API->register_method_mapping) 341#define PyObjC_RegisterSignatureMapping (PyObjC_API->register_signature_mapping) 342#define PyObjC_SizeOfType (PyObjC_API->sizeof_type) 343#define PyObjC_PythonToObjC (PyObjC_API->py_to_objc) 344#define PyObjC_ObjCToPython (PyObjC_API->objc_to_py) 345#define PyObjC_InitSuper (PyObjC_API->fill_super) 346#define PyObjC_InitSuperCls (PyObjC_API->fill_super_cls) 347#define PyObjCPointerWrapper_Register (PyObjC_API->register_pointer_wrapper) 348#define PyObjCUnsupportedMethod_IMP (PyObjC_API->unsupported_method_imp) 349#define PyObjCUnsupportedMethod_Caller (PyObjC_API->unsupported_method_caller) 350#define PyObjCRT_SizeOfType (PyObjC_API->sizeof_type) 351#define PyObjCRT_AlignOfType (PyObjC_API->alignof_type) 352#define PyObjCRT_SELName (PyObjC_API->selname) 353#define PyObjCRT_SimplifySignature (PyObjC_API->simplify_sig) 354#define PyObjC_FreeCArray (PyObjC_API->free_c_array) 355#define PyObjC_PythonToCArray (PyObjC_API->py_to_c_array) 356#define PyObjC_CArrayToPython (PyObjC_API->c_array_to_py) 357#define PyObjC_RegisterStructType (PyObjC_API->register_struct) 358#define PyObjCIMP_GetIMP (PyObjC_API->imp_get_imp) 359#define PyObjCIMP_GetSelector (PyObjC_API->imp_get_sel) 360#define PyObjCObject_IsUninitialized (PyObjC_API->obj_is_uninitialized) 361#define PyObjCObject_New (PyObjC_API->pyobjc_object_new) 362#define PyObjCCreateOpaquePointerType (PyObjC_API->pointer_type_new) 363#define PyObjCObject_NewTransient (PyObjC_API->newtransient) 364#define PyObjCObject_ReleaseTransient (PyObjC_API->releasetransient) 365#define PyObjC_PerformWeaklinking (PyObjC_API->doweaklink) 366#define PyObjCRT_RemoveFieldNames (PyObjC_API->removefields) 367#define PyObjC_NULL (*(PyObjC_API->pyobjc_null)) 368#define PyObjC_DepythonifyCArray (PyObjC_API->dep_c_array_count) 369#define PyObjC_VarList_New (PyObjC_API->varlistnew) 370#define PyObjCObject_Convert (PyObjC_API->pyobjcobject_convert) 371 372typedef void (*PyObjC_Function_Pointer)(void); 373 374typedef struct PyObjC_function_map { 375 const char* name; 376 PyObjC_Function_Pointer function; 377} PyObjC_function_map; 378 379 380 381#ifndef PYOBJC_METHOD_STUB_IMPL 382 383static inline PyObject* 384PyObjC_CreateInlineTab(PyObjC_function_map* map) 385{ 386#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7 387 return PyCObject_FromVoidPtr(map, NULL); 388#else 389 return PyCapsule_New(map, "objc.__inline__", NULL); 390#endif 391} 392 393static inline int 394PyObjC_ImportAPI(PyObject* calling_module) 395{ 396 PyObject* m; 397 PyObject* d; 398 PyObject* api_obj; 399#if PY_MAJOR_VERSION == 2 400 PyObject* name = PyString_FromString("objc"); 401#else 402 PyObject* name = PyUnicode_FromString("objc"); 403#endif 404 405 m = PyImport_Import(name); 406 Py_DECREF(name); 407 if (m == NULL) { 408 return -1; 409 } 410 411 d = PyModule_GetDict(m); 412 if (d == NULL) { 413 PyErr_SetString(PyExc_RuntimeError, 414 "No dict in objc module"); 415 return -1; 416 } 417 418 api_obj = PyDict_GetItemString(d, PYOBJC_API_NAME); 419 if (api_obj == NULL) { 420 PyErr_SetString(PyExc_RuntimeError, 421 "No C_API in objc module"); 422 return -1; 423 } 424#if PY_MAJOR_VERSION == 2 && PY_VERSION_MAJOR < 7 425 PyObjC_API = PyCObject_AsVoidPtr(api_obj); 426#else 427 PyObjC_API = PyCapsule_GetPointer(api_obj, "objc." PYOBJC_API_NAME); 428#endif 429 if (PyObjC_API == NULL) { 430 return 0; 431 } 432 if (PyObjC_API->api_version != PYOBJC_API_VERSION) { 433 PyErr_SetString(PyExc_RuntimeError, 434 "Wrong version of PyObjC C API"); 435 return -1; 436 } 437 438 if (PyObjC_API->struct_len < sizeof(struct pyobjc_api)) { 439 PyErr_SetString(PyExc_RuntimeError, 440 "Wrong struct-size of PyObjC C API"); 441 return -1; 442 } 443 444 Py_INCREF(api_obj); 445 446 /* Current pyobjc implementation doesn't allow deregistering 447 * information, avoid unloading of users of the C-API. 448 * (Yes this is ugle, patches to fix this situation are apriciated) 449 */ 450 Py_INCREF(calling_module); 451 452 return 0; 453} 454#endif /* PYOBJC_METHOD_STUB_IMPL */ 455 456#else /* PyObjC_BUILD */ 457 458extern struct pyobjc_api objc_api; 459 460#endif /* !PYOBJC_BUILD */ 461 462/* 463 * Helper macros to simplify module init functions. 464 */ 465#define PyObjC__STR(x) #x 466#define PyObjC_STR(x) PyObjC__STR(x) 467 468#if PY_MAJOR_VERSION == 3 469 470#define PyObjC_INITERROR() return NULL 471#define PyObjC_INITDONE() return m 472 473 474#define PyObjC_MODULE_INIT(name) \ 475 static struct PyModuleDef mod_module = { \ 476 PyModuleDef_HEAD_INIT, \ 477 PyObjC_STR(name), \ 478 NULL, \ 479 0, \ 480 mod_methods, \ 481 NULL, \ 482 NULL, \ 483 NULL, \ 484 NULL \ 485 }; \ 486 \ 487 PyObject* PyInit_##name(void); \ 488 PyObject* PyInit_##name(void) 489 490#define PyObjC_MODULE_CREATE(name) \ 491 PyModule_Create(&mod_module); 492 493#else 494 495#define PyObjC_INITERROR() return 496#define PyObjC_INITDONE() return 497 498#define PyObjC_MODULE_INIT(name) \ 499 void init##name(void); \ 500 void init##name(void) 501 502#define PyObjC_MODULE_CREATE(name) \ 503 Py_InitModule4(PyObjC_STR(name), mod_methods, \ 504 NULL, NULL, PYTHON_API_VERSION); 505 506#endif 507 508#endif /* PyObjC_API_H */ 509