1/* 2 * This file defines the glue code that is needed to access the objc module 3 * from other modules. 4 * 5 * Why would you want to do that? 6 * - To wrap native functions that use Objective-C objects as arguments or 7 * return values 8 * - To add custom wrappers for troublesome methods in specific classes 9 * - To generic support for additional method signatures 10 */ 11#include "pyobjc.h" 12 13#ifdef PyObjCObject_GetObject 14#undef PyObjCObject_GetObject 15#endif 16 17 18static void do_weaklink(PyObject* module_dict, struct PyObjC_WeakLink* funcs) 19{ 20 while (funcs->name) { 21 if (!funcs->func) { 22 if (PyDict_DelItemString( 23 module_dict, 24 funcs->name) == -1) { 25 PyErr_Clear(); 26 } 27 } 28 funcs++; 29 } 30} 31 32static int obj_is_uninitialized(PyObject* object) 33{ 34 if (!PyObjCObject_Check(object)) { 35 return -1; 36 } 37 return (PyObjCObject_GetFlags(object) & PyObjCObject_kUNINITIALIZED) != 0; 38} 39 40static id python_to_id(PyObject* object) 41{ 42 id result; 43 int err; 44 45 err = depythonify_c_value(@encode(id), object, &result); 46 if (err == -1) { 47 return nil; 48 } 49 50 return result; 51} 52 53static PyObject* id_to_python(id object) 54{ 55 PyObject* result; 56 57 result = pythonify_c_value(@encode(id), &object); 58 return result; 59} 60 61static Class sel_get_class(PyObject* sel) 62{ 63 if (!PyObjCNativeSelector_Check(sel)) { 64 PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector"); 65 return NULL; 66 } 67 return ((PyObjCNativeSelector*)sel)->sel_class; 68} 69 70static SEL sel_get_sel(PyObject* sel) 71{ 72 if (!PyObjCSelector_Check(sel)) { 73 PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector"); 74 return NULL; 75 } 76 return ((PyObjCSelector*)sel)->sel_selector; 77} 78 79static void fill_super(struct objc_super* super, Class cls, id receiver) 80{ 81 objc_superSetReceiver(*super, receiver); 82 objc_superSetClass(*super, cls); 83} 84 85static void fill_super_cls(struct objc_super* super, Class cls, Class self) 86{ 87 objc_superSetReceiver(*super, self); 88 objc_superSetClass(*super, object_getClass(cls)); 89} 90 91static int depythonify_c_array_count2(const char* type, Py_ssize_t count, BOOL strict, PyObject* value, void* datum) 92{ 93 return depythonify_c_array_count(type, count, strict, value, datum, NO, NO); 94} 95 96 97 98 99struct pyobjc_api objc_api = { 100 PYOBJC_API_VERSION, /* api_version */ 101 sizeof(struct pyobjc_api), /* struct_size */ 102 &PyObjCClass_Type, /* class_type */ 103 (PyTypeObject*)&PyObjCObject_Type, /* object_type */ 104 &PyObjCSelector_Type, /* select_type */ 105 (RegisterMethodMappingFunctionType*)PyObjC_RegisterMethodMapping, /* register_method_mapping */ 106 (int (*)(char*, PyObject *(*)(PyObject*, PyObject*, PyObject*), void (*)(void*, void*, void**, void*)))PyObjC_RegisterSignatureMapping, /* register_signature_mapping */ 107 PyObjCObject_GetObject, /* obj_get_object */ 108 PyObjCObject_ClearObject, /* obj_clear_object */ 109 PyObjCClass_GetClass, /* cls_get_class */ 110 PyObjCClass_New, /* cls_to_python */ 111 python_to_id, /* python_to_id */ 112 id_to_python, /* id_to_python */ 113 PyObjCErr_FromObjC, /* err_objc_to_python */ 114 PyObjCErr_ToObjC, /* err_python_to_objc */ 115 depythonify_c_value, /* py_to_objc */ 116 pythonify_c_value, /* objc_to_python */ 117 PyObjCRT_SizeOfType, /* sizeof_type */ 118 sel_get_class, /* sel_get_class */ 119 sel_get_sel, /* sel_get_sel */ 120 fill_super, /* fill_super */ 121 fill_super_cls, /* fill_super_cls*/ 122 PyObjCPointerWrapper_Register, /* register_pointer_wrapper */ 123 (void(*)(void*,void*,void**,void*))PyObjCUnsupportedMethod_IMP, /* unsupported_method_imp */ 124 PyObjCUnsupportedMethod_Caller, /* unsupported_method_caller */ 125 PyObjCErr_ToObjCWithGILState, /* objc_err_to_objc_gil */ 126 PyObjCRT_AlignOfType, /* alignof_type */ 127 sel_getName, /* selname */ 128 PyObjCRT_SimplifySignature, /* simplify_sig */ 129 PyObjC_FreeCArray, /* free_c_array */ 130 PyObjC_PythonToCArray, /* py_to_c_array */ 131 PyObjC_CArrayToPython, /* c_array_to_py */ 132 PyObjC_RegisterStructType, /* register_struct */ 133 &PyObjCIMP_Type, /* imp_type */ 134 PyObjCIMP_GetIMP, /* imp_get_imp */ 135 PyObjCIMP_GetSelector, /* imp_get_sel */ 136 PyObjCErr_AsExc, /* err_python_to_nsexception */ 137 PyGILState_Ensure, /* gilstate_ensure */ 138 obj_is_uninitialized, /* obj_is_uninitialized */ 139 PyObjCObject_New, /* pyobjc_object_new */ 140 PyObjCCreateOpaquePointerType, /* pointer_type_new */ 141 PyObjCObject_NewTransient, /* newtransient */ 142 PyObjCObject_ReleaseTransient, /* releasetransient */ 143 do_weaklink, /* doweaklink */ 144 PyObjCRT_RemoveFieldNames, /* removefields */ 145 &PyObjC_NULL, /* PyObjC_NULL */ 146 depythonify_c_array_count2, /* PyObjC_DepythonifyCArray */ 147 PyObjC_VarList_New, /* PyObjC_VarList_New */ 148 PyObjC_is_ascii_string, 149 PyObjC_is_ascii_prefix, 150 PyObjCObject_Convert, 151}; 152 153int PyObjCAPI_Register(PyObject* module) 154{ 155#if PY_MAJOR_VERSION == 2 156 PyObject* API = PyCObject_FromVoidPtr(&objc_api, NULL); 157#else 158 PyObject* API = PyCapsule_New(&objc_api, "objc." PYOBJC_API_NAME, NULL); 159#endif 160 161 if (API == NULL) return -1; 162 163 if (PyModule_AddObject(module, PYOBJC_API_NAME, API) < 0) { 164 Py_DECREF(API); 165 return -1; 166 } 167 return 0; 168} 169