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