1

I'm working with a C++ class which I CANNOT modify that declares an extern "C" function from within a cpp file (not a .h).

How do I call that function from another cpp file?

To further complicate matters, the function is declared with the "weak" attribute, and as such I can overwrite it. What I'm really trying to do is call that weak function from my strong function in a manner analogous to calling a base class function from a derived class which is overriding the function.

  • MORE -

Alright let's get really specific since ppl are asking for more info...

I'm creating a Qt 5.5 project for an iOS App. I found a bug where Qt will crash if you load the app face up. See thread: Qt for iOS locks up when app is launched face up. (qiosscreen.mm assertion)

I am NOT building from the Qt source. I am using it out of the box. I can see the cpp source, but I cannot actually modify or include it.

I figured out a way with a static class to detect that my problem will occur before it does. Since I don't actually know how to fix it, I want to display an error message at least rather than just having the app go to a black screen when you launch it.

Qt iOS apps load using the class "qioseventdispatcher". The cpp (which I can't change or include) declares a weak main function and another weak function called qtmn. You are suppose to override qtmn as your "main" function - which this qt class calls. You can, however, override the "real" main too and create your own native app without the qt underlying layers.

I want to determine at RUNTIME (I can do this at compile time now) if I'm going to have the qt functions called or my own to load a simple native app that will display an error message.

Here's some of the qt cpp:

    extern "C" int __attribute__((weak)) main(int argc, char *argv[])
    {
        @autoreleasepool {
  ...
            qEventDispatcherDebug() << "Running UIApplicationMain"; qIndent();
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));
        }
    }

  ...

    // We define qtmn so that user_main_trampoline() will not cause
    // missing symbols in the case of hybrid applications that don't
    // use our main wrapper. Since the symbol is weak, it will not
    // get used or cause a clash in the normal Qt application usecase,
    // where we rename main to qtmn before linking.
    extern "C" int __attribute__((weak)) qtmn(int argc, char *argv[])
    {
        Q_UNUSED(argc);
        Q_UNUSED(argv);

        Q_UNREACHABLE();
    }

qtmn() goes on the get called by the UIApplication selector (void) applicationDidFinishLaunching.

I want to provide a "strong" copy of main, and a strong copy of qtmn(). My copy of main will decide to load my native app, or call the qt weak main function somehow, which will then call my qtmn() function in the standar Qt for iOS manner.

Community
  • 1
  • 1
BuvinJ
  • 10,221
  • 5
  • 83
  • 96
  • 1
    It isn't quite clear what you mean by a class declaring an extern "C" function. Can you show some code? – n. m. could be an AI Sep 30 '15 at 21:16
  • 2
    Can't you just put `extern "C"` around the declaration of the function in the second file? Since you put this around the definition in the first file, it will be compiled as if it were in a C program, and the caller will call it like a C function. – Barmar Sep 30 '15 at 21:22
  • I don't see why not. extern "C" has to do with compiler linkage http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c – Aidan Gomez Sep 30 '15 at 21:42
  • I've used extern "C" with dlls and GetProcAddress to get a function pointer. Is there maybe something similar I could do here? – BuvinJ Sep 30 '15 at 21:56
  • The easiest way i can think of would not answer your question but is maybe an acceptable workaround. What about building two versions of your app. And the strong one executes the weak one if supppsed to? – fassl Oct 05 '15 at 23:05
  • Fassl, that's a good suggestion. I thought of that as possibility too. I could definitely do that with say a Windows exe. I'm not sure how to accomplish that though with an iOS app. How do I launch "another app", but keep them bundled within one? I don't want to have two icons on the desktop, and I certainly don't want to deal with code signing, app store submission, dual downloading / syncing, etc. – BuvinJ Oct 06 '15 at 13:08
  • Also, if anyone checks out the link I posted regarding my primary reason for doing this, you'll see that I kind of "solved" that one without doing this alternate app deal. I still want this option though as a way to "bail" on Qt before using it for any number of potential reasons in the future. – BuvinJ Oct 06 '15 at 13:11
  • I guess it is kind of an archive or folder like on Mac OS .app. If so and there is something like execve or any of its alternatives you could launch the other app. Or you build the weak one with your strong function being called something else, and you binary patch the final executable to jump to your function from within the weak one, restore the actual instructions and jump back... well pretty messy and probably not so easy to automate... probably possible, worth the effort? I don't know, can't think of anything easier at the moment. – fassl Oct 09 '15 at 20:59

0 Answers0