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 17static void do_weaklink(PyObject* module_dict, struct PyObjC_WeakLink* funcs) 18{ 19 while (funcs->name) { 20 if (!funcs->func) { 21 if (PyDict_DelItemString( 22 module_dict, 23 funcs->name) == -1) { 24 PyErr_Clear(); 25 } 26 } 27 funcs++; 28 } 29} 30 31static int obj_is_uninitialized(PyObject* object) 32{ 33 if (!PyObjCObject_Check(object)) { 34 return -1; 35 } 36 return (PyObjCObject_GetFlags(object) & PyObjCObject_kUNINITIALIZED) != 0; 37} 38 39static id python_to_id(PyObject* object) 40{ 41 id result; 42 int err; 43 44 err = depythonify_c_value(@encode(id), object, &result); 45 if (err == -1) { 46 return nil; 47 } 48 49 return result; 50} 51 52static PyObject* id_to_python(id object) 53{ 54 PyObject* result; 55 56 result = pythonify_c_value(@encode(id), &object); 57 return result; 58} 59 60static Class sel_get_class(PyObject* sel) 61{ 62 if (!PyObjCNativeSelector_Check(sel)) { 63 PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector"); 64 return NULL; 65 } 66 return ((PyObjCNativeSelector*)sel)->sel_class; 67} 68 69static SEL sel_get_sel(PyObject* sel) 70{ 71 if (!PyObjCSelector_Check(sel)) { 72 PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector"); 73 return NULL; 74 } 75 return ((PyObjCSelector*)sel)->sel_selector; 76} 77 78static void fill_super(struct objc_super* super, Class cls, id receiver) 79{ 80 objc_superSetReceiver(*super, receiver); 81 objc_superSetClass(*super, cls); 82} 83 84static void fill_super_cls(struct objc_super* super, Class cls, Class self) 85{ 86 objc_superSetReceiver(*super, self); 87 objc_superSetClass(*super, object_getClass(cls)); 88} 89 90static int depythonify_c_array_count2(const char* type, Py_ssize_t count, BOOL strict, PyObject* value, void* datum) 91{ 92 return depythonify_c_array_count(type, count, strict, value, datum, NO, NO); 93} 94 95 96 97 98struct pyobjc_api objc_api = { 99 PYOBJC_API_VERSION, /* api_version */ 100 sizeof(struct pyobjc_api), /* struct_size */ 101 &PyObjCClass_Type, /* class_type */ 102 (PyTypeObject*)&PyObjCObject_Type, /* object_type */ 103 &PyObjCSelector_Type, /* select_type */ 104 (RegisterMethodMappingFunctionType*)PyObjC_RegisterMethodMapping, /* register_method_mapping */ 105 (int (*)(char*, PyObject *(*)(PyObject*, PyObject*, PyObject*), void (*)(void*, void*, void**, void*)))PyObjC_RegisterSignatureMapping, /* register_signature_mapping */ 106 PyObjCObject_GetObject, /* obj_get_object */ 107 PyObjCObject_ClearObject, /* obj_clear_object */ 108 PyObjCClass_GetClass, /* cls_get_class */ 109 PyObjCClass_New, /* cls_to_python */ 110 python_to_id, /* python_to_id */ 111 id_to_python, /* id_to_python */ 112 PyObjCErr_FromObjC, /* err_objc_to_python */ 113 PyObjCErr_ToObjC, /* err_python_to_objc */ 114 depythonify_c_value, /* py_to_objc */ 115 pythonify_c_value, /* objc_to_python */ 116 PyObjCRT_SizeOfType, /* sizeof_type */ 117 sel_get_class, /* sel_get_class */ 118 sel_get_sel, /* sel_get_sel */ 119 fill_super, /* fill_super */ 120 fill_super_cls, /* fill_super_cls*/ 121 PyObjCPointerWrapper_Register, /* register_pointer_wrapper */ 122 (void(*)(void*,void*,void**,void*))PyObjCUnsupportedMethod_IMP, /* unsupported_method_imp */ 123 PyObjCUnsupportedMethod_Caller, /* unsupported_method_caller */ 124 PyObjCErr_ToObjCWithGILState, /* objc_err_to_objc_gil */ 125 PyObjCRT_AlignOfType, /* alignof_type */ 126 sel_getName, /* selname */ 127 PyObjCRT_SimplifySignature, /* simplify_sig */ 128 PyObjC_FreeCArray, /* free_c_array */ 129 PyObjC_PythonToCArray, /* py_to_c_array */ 130 PyObjC_CArrayToPython, /* c_array_to_py */ 131 PyObjC_RegisterStructType, /* register_struct */ 132 &PyObjCIMP_Type, /* imp_type */ 133 PyObjCIMP_GetIMP, /* imp_get_imp */ 134 PyObjCIMP_GetSelector, /* imp_get_sel */ 135 PyObjCErr_AsExc, /* err_python_to_nsexception */ 136 PyGILState_Ensure, /* gilstate_ensure */ 137 obj_is_uninitialized, /* obj_is_uninitialized */ 138 PyObjCObject_Convert, /* pyobjcobject_convert */ 139 PyObjCSelector_Convert, /* pyobjcselector_convert */ 140 PyObjCClass_Convert, /* pyobjcclass_convert */ 141 PyObjC_ConvertBOOL, /* pyobjc_convertbool */ 142 PyObjC_ConvertChar, /* pyobjc_convertchar */ 143 PyObjCObject_New, /* pyobjc_object_new */ 144 PyObjCCreateOpaquePointerType, /* pointer_type_new */ 145 PyObjCObject_NewTransient, /* newtransient */ 146 PyObjCObject_ReleaseTransient, /* releasetransient */ 147 do_weaklink, /* doweaklink */ 148 PyObjCRT_RemoveFieldNames, /* removefields */ 149 &PyObjC_NULL, /* PyObjC_NULL */ 150 depythonify_c_array_count2, /* PyObjC_DepythonifyCArray */ 151 PyObjC_VarList_New, /* PyObjC_VarList_New */ 152}; 153 154int PyObjCAPI_Register(PyObject* module) 155{ 156 PyObject* API = PyCObject_FromVoidPtr(&objc_api, NULL); 157 158 if (API == NULL) return -1; 159 160 if (PyModule_AddObject(module, PYOBJC_API_NAME, API) < 0) { 161 Py_DECREF(API); 162 return -1; 163 } 164 return 0; 165} 166