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