void *createDataSource() { Class superclass = (Class) objc_getClass("NSObject"); Class DataSource = objc_allocateClassPair(superclass, "DataSource", 0); class_addMethod(DataSource, sel_registerName("tableView:numberOfRowsInSection:"), (void(*))tableView_numberOfRowsInSection, nil); class_addMethod(DataSource, sel_registerName("tableView:cellForRowAtIndexPath:"), (void(*))tableView_cellForRowAtIndexPath, nil); objc_registerClassPair(DataSource); return class_createInstance(DataSource, 0); }
//Create an class named "AppDelegate", and return it's name as an instance of class NSString void *createAppDelegate() { Class mySubclass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "AppDelegate", 0); struct objc_selector *selName = sel_registerName("application:didFinishLaunchingWithOptions:"); class_addMethod(mySubclass, selName, (void(*))applicationdidFinishLaunching, nil); objc_registerClassPair(mySubclass); return objc_msgSend(objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), "AppDelegate"); }
void * createDelegate() { Class superclass = (Class) objc_getClass("NSObject"); Class DataSource = objc_allocateClassPair(superclass, "Delegate", 0); class_addMethod(DataSource, sel_registerName("tableView:didSelectRowAtIndexPath:"), (void(*))tableView_didSelectRowAtIndexPath, nil); objc_registerClassPair(DataSource); return class_createInstance(DataSource, 0); }
PCloudApp::PCloudApp(int &argc, char **argv) : QApplication(argc, argv) { #ifdef Q_OS_MAC objc_class * cls = objc_getClass("NSApplication"); SEL sharedApplication = sel_registerName("sharedApplication"); objc_object* appInst = objc_msgSend((objc_object*) cls,sharedApplication); if(appInst != NULL) { objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate")); objc_object* delClass = objc_msgSend(delegate, sel_registerName("class")); class_addMethod((Class)delClass, sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"), (IMP)dockClickHandler,"B@:"); } #endif #ifdef Q_OS_WIN notifythread = NULL; #endif reglog=NULL; regwin=NULL; logwin=NULL; loggedmenu=NULL; settingswin=NULL; sharefolderwin=NULL; incomingshareswin=NULL; outgoingshareswin=NULL; mthread=NULL; loggedin=false; lastMessageType=-1; createMenus(); settings=new PSettings(this); tray=new QSystemTrayIcon(this); tray->setIcon(QIcon(OFFLINE_ICON)); tray->setContextMenu(notloggedmenu); tray->setToolTip("pCloud"); connect(tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClicked(QSystemTrayIcon::ActivationReason))); connect(tray, SIGNAL(messageClicked()), this, SLOT(trayMsgClicked())); connect(this, SIGNAL(logInSignal(QString, QString, quint64, bool, bool, quint64, quint64, bool)), this, SLOT(logIn(QString, QString, quint64,bool, bool, quint64, quint64, bool))); connect(this, SIGNAL(showLoginSignal()), this, SLOT(showLogin())); pCloudWin = new PCloudWindow(this); pCloudWin->layout()->setSizeConstraint(QLayout::SetFixedSize); //for auto resize pCloudWin->setOnlineItems(false); tray->show(); if (settings->isSet("auth") && settings->get("auth").length() > 0){ this->authentication = settings->get("auth"); othread=new OnlineThread(this); othread->start(); } else{ othread=NULL; emit showLoginSignal(); } }
int main(int argc,const char* argv[]) { //新创建一个Class对象,继承于NSObject,名字叫NSPower(用于注册一个Class,Class的名字叫NSPower) Class powerCls = objc_allocateClassPair(objc_getClass("NSObject"), "NSPower", 0); //定义一个SEL,也就是OC里面的Selector,我理解为一个方法的Key,通过这个名字可以找到一个对应的方法实现函数 SEL selFun = sel_registerName("fun"); //为这个Class添加一个方法,名字叫fun,实现为power_fun(之前声明的一个C函数) //后面这个字符串是干嘛的呢?用来说明参数的,OC语言特别为每种参数类型指定了一个编码 //比如V@:的意思是,返回值是void,第一个参数是id,第二个参数是SEL class_addMethod(powerCls, selFun, (IMP)power_fun, "V@:"); //注册这个Class,从此以后,你就可以使用NSPower这个名字来创建一个类的实例了 objc_registerClassPair(powerCls); //以下代码就是创建一个NSPower的实例,并且调用fun方法 //得到一个class的实例 Class cls = objc_getClass("NSPower"); //对这个class发送alloc消息,创建一个class对象 id obj = objc_msgSend((id)cls,sel_registerName("alloc")); //对这个对象发送一个fun消息,这样会调用到之前的power_fun方法 objc_msgSend(obj,selFun); return 0; }
void SwizzInstanceMethod(Class origClass, Class replaceClass, SEL origSel, SEL replaceSel) { Method origMethod = class_getInstanceMethod(origClass, origSel); Method newMethod = class_getInstanceMethod(replaceClass, replaceSel); if(class_addMethod(origClass, origSel, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) class_replaceMethod(origClass, replaceSel, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); else method_exchangeImplementations(origMethod, newMethod); }
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types) { Method method = class_getInstanceMethodNonrecursive(cls, name); IMP old; if (method == NULL) { class_addMethod(cls, name, imp, types); return NULL; } old = (IMP) method->method_imp; method->method_imp = (objc_imp_gnu) imp; return old; }
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types) { if (Nil == cls) { return (IMP)0; } SEL sel = sel_registerTypedName_np(sel_getName(name), types); Method method = class_getInstanceMethodNonrecursive(cls, sel); if (method == NULL) { class_addMethod(cls, sel, imp, types); return NULL; } IMP old = (IMP)method->imp; method->imp = imp; if (objc_test_class_flag(cls, objc_class_flag_resolved)) { objc_update_dtable_for_class(cls); } return old; }
bool OBJC_EXCHANGE_NEWCLASS_METHOD_TEMPLATE(const char* orgClassStr,const char* orgSelector, const char* newClassStr,const char* newSelector) { Class orgClass = objc_getClass(orgClassStr); Class newClass = objc_getClass(newClassStr); if(!orgClass || !newClass) { return false; } SEL orgMethod = sel_registerName(orgSelector); SEL newMethod = sel_registerName(newSelector); Method newMethodIns = class_getInstanceMethod(newClass, newMethod); /*在旧的类添加类新方法后,那么只需要交换原有的方法即可*/ Method orgMethodIns = class_getInstanceMethod(orgClass, orgMethod); /*防止方法不存在*/ if(!orgMethodIns || !newMethodIns) { return false; } IMP newMethodIMP = method_getImplementation(newMethodIns); const char *newMethodStr = method_getTypeEncoding(newMethodIns); class_addMethod(orgClass, newMethod, newMethodIMP, newMethodStr); newMethodIns = class_getInstanceMethod(orgClass, newMethod); method_exchangeImplementations(orgMethodIns, newMethodIns); return true; }
FDNDApplication::FDNDApplication(int argc, char *argv[]) : QtSingleApplication(argc, argv) { #ifdef Q_OS_MAC Class cls = objc_getClass("NSApplication"); SEL sharedApplication = sel_registerName("sharedApplication"); objc_object *appInst = objc_msgSend((objc_object*)cls,sharedApplication); if(appInst != NULL) { objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate")); objc_object* delClass = objc_msgSend(delegate, sel_registerName("class")); //const char* tst = class_getName(delClass->isa); bool test = class_addMethod((Class)delClass, sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"), (IMP)dockClickHandler,"B@:"); if (!test) { LogManager::appendLine("[FDNDApplication] Cannot get dock handler"); } } #endif }
void* UndefMgr::generateNew(const char* name) { bool isClass = (strncmp(name, "OBJC_CLASS", 10) == 0); bool isMetaClass = (strncmp(name, "OBJC_METACLASS", 14) == 0); if (isClass || isMetaClass) { // Strip the OBJC_CLASS_$_ or OBJC_METACLASS_$_ name = &name[(isMetaClass) ? 17 : 13]; // Objective-C class or metaclass info static std::map<std::string, Class> undefClasses; Class classStub = nullptr; auto classIter = undefClasses.find(name); if (classIter != undefClasses.end()) { classStub = classIter->second; } else if (NULL == (classStub = (Class)objc_getClass(name))) { classStub = objc_allocateClassPair(nullptr, name, 0); if (isMetaClass) { // Put in a dummy initialize method that lets us know the class got used IMP imp = reinterpret_cast<IMP>(&UndefinedClassInitialize); SEL sel = sel_registerTypedName_np("initialize", NULL); class_addMethod(object_getClass(reinterpret_cast<id>(classStub)), sel, imp, NULL); } objc_registerClassPair(classStub); Darling::MachOMgr::instance()->registerNativeClass(object_getClass(reinterpret_cast<id>(classStub))); Darling::MachOMgr::instance()->registerNativeClass(classStub); fprintf(stderr, "Undef class for class %s at %p\n", class_getName(classStub), classStub); undefClasses[name] = classStub; } return (isClass) ? classStub : object_getClass(reinterpret_cast<id>(classStub)); } else if (strncmp(name, "OBJC_IVAR", 9) == 0) { // Objective-C ivar typedef struct { const char *name; const char *type; int offset; } objc_ivar; objc_ivar *ivarStub = new objc_ivar; ivarStub->name = &name[12]; ivarStub->type = ""; ivarStub->offset = 0; return ivarStub; } else { // Generate a function stub UndefinedFunction * uf = new UndefinedFunction(); uf->init(name); return uf->getPointer(); } }
bool NSGLWindow::initialize() { // Strong reference to the class of the AppDelegate (same as [AppDelegate class]) static Class appDelClass = nullptr; if (not appDelClass) { appDelClass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "AppDelegate", 0); class_addMethod(appDelClass, sel_getUid("applicationDidFinishLaunching:"), (IMP)OnAppDidFinishLaunching, "i@:@"); objc_registerClassPair(appDelClass); } // Tell the runtime to create a new class, a subclass of 'NSOpenGLView' named 'YView'. static Class viewClass = nullptr; if (not viewClass) { viewClass = objc_allocateClassPair((Class)objc_getClass("NSOpenGLView"), "YView", 0); // Tell the runtime to add functions for various events to our custom view. class_addMethod(viewClass, sel_getUid("drawRect:"), (IMP)NSGLWindow::OnDrawRect, "v@:"); class_addMethod(viewClass, sel_getUid("mouseDown:"), (IMP)NSGLWindow::OnMouseDown, "v@:"); //class_addMethod(viewClass, sel_getUid("close:"), (IMP)NSGLWindow::OnWindowClose, "v@:"); // And again, we tell the runtime that this class is now valid to be used. // At this point, the application should run and display the screenshot shown below. objc_registerClassPair(viewClass); } cmacs_simple_msgSend((id)objc_getClass("NSApplication"), sel_getUid("sharedApplication")); if (not NSApp) { std::cerr << "Failed to initialized NSApplication... terminating..." << std::endl; return false; } // Create the app delegate static AppDelegate* appDelObj = nullptr; if (not appDelObj) { appDelObj = (AppDelegate*)cmacs_simple_msgSend((id)objc_getClass("AppDelegate"), sel_getUid("alloc")); appDelObj = (AppDelegate*)cmacs_simple_msgSend((id)appDelObj, sel_getUid("init")); cmacs_void_msgSend1(NSApp, sel_getUid("setDelegate:"), appDelObj); // Launch main loop //cmacs_void_msgSend(NSApp, sel_getUid("run")); } appDelObj->window = cmacs_simple_msgSend((id)objc_getClass("NSOpenGLWindow"), sel_getUid("alloc")); /// Create an instance of the window. appDelObj->window = cmacs_window_init_msgSend(appDelObj->window, sel_getUid("initWithContentRect:styleMask:backing:defer:"), (CMRect){ {0,0},{1024,460}}, (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask), 0, false); /// Create an instance of our view class. /// /// Relies on the view having declared a constructor that allocates a class pair for it. id view = cmacs_rect_msgSend1(cmacs_simple_msgSend((id)objc_getClass("YView"), sel_getUid("alloc")), sel_getUid("initWithFrame:"), (CMRect){ {0, 0}, {640, 480} }); // here we simply add the view to the window. cmacs_void_msgSend1(appDelObj->window, sel_getUid("setContentView:"), view); cmacs_simple_msgSend(appDelObj->window, sel_getUid("becomeFirstResponder")); // Shows our window in the bottom-left hand corner of the screen. //cmacs_void_msgSend1(appDelObj->window, sel_getUid("makeKeyAndOrderFront:"), appDelObj); return true; }