0

I have several libraries, each of which implement a class (derived from QObject). I would like each of these libraries to execute a function the first time they load. I found a couple of similar questions here:

Automatically executed functions when loading shared libraries

and

How exactly does __attribute__((constructor)) work?

but any initialization function I create based on the answers never executes. I've tried creating the function in a namespace, outside a namespace (and not a part of my class), using __attribute__((constructor)), naming it _init, and specifying the function name to the linker with:

QMAKE_LFLAGS_RELEASE += -Wl,-init,libinitfunc

None of these have worked.

I should also note that I'm cross-compiling these libraries to run on an embedded ARM device that uses busybox for much of its functionality.

Community
  • 1
  • 1
zarprime
  • 3
  • 4

1 Answers1

2

Since this is C++ code, you shouldn't need C-style hacks.

class LibInstance {
public:
  LibInstance() {
    qDebug() << __FILE__ << "has been initialized";
  }
  ~LibInstance() {
    qDebug() << __FILE__ << "has been unloaded";
  }
}

Q_GLOBAL_STATIC(LibInstance, libInstance)

class LibExecutor {
  LibExecutor() { libInstance(); }
};
static LibExecutor libExecutor;

An instance of LibExecutor is guaranteed to be constructed, in a non-threadsafe way, before main() starts running; or before the library finishes loading, if it's demand-loaded. The LibExecutor's constructor is then using the Q_GLOBAL_STATIC implementation to thread-safely execute the LibInstance's constructor.

It is in LibInstance's constructor that you place the initialization functionality you desire. The destructor will be called when the library is being unloaded.

It is generally safe, cross platform, and used within Qt itself.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • So I tried this, and it works, assuming that the intent is that the application loading the library should know to call libInit(). I'd hoped for automatic initialization, but this may be better as ideally these libraries should build for an x86 Windows environment as well. Having a custom init mechanism may be preferable to trying to use the very different ones for Linux and Windows. – zarprime Mar 11 '14 at 20:57
  • Oops. I built a release version of my lib, which has QDebug messages suppressed. After enabling them, this does exactly what it is supposed to do (which is to say, runs automatically on load; libInit does not need to be called from the executable). – zarprime Mar 13 '14 at 15:04
  • @zarprime libInit is not a function, just a class instance. There's no way to call it, and nobody expects you to even think about calling it. Yes, if you'd add `operator()()` to `LibInit`, you could pull that off, but it'd be rather pointless. – Kuba hasn't forgotten Monica Mar 13 '14 at 15:29
  • Yeah, my mistake became clear to me when I came across a very similar question: http://stackoverflow.com/questions/1602398/linux-dlopen-can-a-library-be-notified-when-it-is-loaded and I had to do some research on Q_GLOBAL_STATIC (which exists, but has no help in Qt 4.8). – zarprime Mar 13 '14 at 20:29
  • I've amended my example. You were of course right that the operator()() has to be called for the object to be constructed. I've shown how to do avoid having to do that. – Kuba hasn't forgotten Monica Mar 17 '14 at 19:01