[Interest] Objective C Category for QCocoaApplicationDelegate undefined symbols
Croitor Alexandru
placinta at gmail.com
Tue Jul 14 12:57:53 CEST 2015
Thanks for the suggestions. I'll check if I'll be able to link against the
base protocol (maybe with the use of the mentioned library).
For the time being, I was able to solve the problem using method swizzling,
by replacing the method provided by Qt with my own Block (lambda). I am
aware that overriding methods this way is not a best practice, but it looks
like the only way without modifying Qt's platform plugin source code, and
compiling my own Qt.
The pseudo-code looks something like this, in case if anyone needs to do
the same.
BOOL SwizzleReplaceMethodWithBlock(Class c, SEL origSEL, SEL newSEL, id block) {
if ([c respondsToSelector:newSEL]) return YES; // Selector already
implemented, skip
Method origMethod = class_getInstanceMethod(c, origSEL);
// Add the new method.
IMP impl = imp_implementationWithBlock(block);
if (!class_addMethod(c, newSEL, impl, method_getTypeEncoding(origMethod))) {
NSLog(@"Failed to add method: %@ on %@",
NSStringFromSelector(newSEL), c);
return NO;
}else {
Method newMethod = class_getInstanceMethod(c, newSEL);
// If original doesn't implement the method we want to
swizzle, create it.
if (class_addMethod(c, origSEL,
method_getImplementation(newMethod),
method_getTypeEncoding(origMethod))) {
class_replaceMethod(c, newSEL,
method_getImplementation(origMethod),
method_getTypeEncoding(newMethod));
}else {
method_exchangeImplementations(origMethod, newMethod);
}
}
return YES;
}
Class qtAppDelegateClass = [[[NSApplication sharedApplication] delegate] class];
SEL newAppDelegateLaunchSelector =
NSSelectorFromString(@"myAppDelegateApplicationDidFinishLaunching:");
SwizzleReplaceMethodWithBlock(qtAppDelegateClass,
@selector(applicationDidFinishLaunching:),
newAppDelegateLaunchSelector, ^(NSObject* _self, NSNotification*
aNotification) {
NSLog(@"applicationDidFinishLaunching before Qt method");
// Call the original method.
((void ( *)(id, SEL, NSNotification *))objc_msgSend)(_self,
newAppDelegateLaunchSelector, aNotification);
NSLog(@"The notification with which the app started is %@",
aNotification);
NSLog(@"applicationDidFinishLaunching after Qt method");
});
>Anyway, my general idea, as you have figured out, is to extend QCocoaApplicationDelegate's "base class" (or Protocol), which I guess is an NSWhatever class/protocol. Then simply link your application explicitly with -lcocoa (or the correct framework/if needed).
>Maybe that gets you some ideas...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20150714/28b6dcb9/attachment.html>
More information about the Interest
mailing list