[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