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