Coyote
Coyote

Reputation: 2524

C++ Executing functions when a static library is loaded

I need to register classes when the code is loading. I implemented a solution which works great as long as the code is compiled in the app.

But when the code is provided by a static library it doesn't work at all.

I solved this problem in a fashion similar to this answer: https://stackoverflow.com/a/729028/171711.

Currently I have something like:

#define REGISTER(className)\
static const int __classDescriptor##className = MyRegister(#className, className::GetAllocator());

When used it looks like:

//Foo.cpp

REGISTER(Foo);

Foo::Foo()
{
  ...
}

And I have in the logs:

registered class:Foo

But when I created a static library and Foo is provided by the library the problem is that REGISTER(Foo); is never called.

I have a complex loading system to allow scripts to use native C++ classes which is dependent on this behavior. Is there a way to force the code in Foo.cpp to execute when the library is loaded?


Edit: It seems my question is directly related to the one about static linking in Visual Studio. It seems I have the same problem with my own libraries. I noticed that some of the classes from the library are registered. And they are only the ones which have their .h file included in my project.

So is there a way to execute code in a lib without linking to the .h file?

Upvotes: 3

Views: 2797

Answers (2)

Taylor
Taylor

Reputation: 6430

Use the -all_load linker option to load all members of static libraries. Or for a specific library, use -force_load path_to_archive.

In Xcode, you'll want to add these options under "Other Linker Flags" for your executable (not your static library).

This fixed the problem for my static initialization functions.

Upvotes: 4

Coyote
Coyote

Reputation: 2524

The only way to initialize my classes descriptors before any other code relying on them is called is to initialize the library.

I added a function MyLibraryInit() which calls a function on each __classDescriptor##className to force the initialization of each descriptor.

Unfortunately it seems to be the most elegant approach I could find.

Upvotes: 1

Related Questions