I have a program that statically links with several c++ libraries that export a few functions:
extern "C"
{
KSrvRequestHandler* CreateRequestHandler( const char* name );
bool DestroyRequestHandler( KSrvRequestHandler* handler );
const char** ListRequestHandlerTypes();
}
The main program then calls these functions using GetProcAddress/dlsym:
#ifdef WIN32
HINSTANCE hDll = GetModuleHandle( NULL );
mCreateHandler = GetProcAddress( hDll, createFuncName );
mDestroyHandler = GetProcAddress( hDll, destroyFuncName );
mGetHandlerTypes = GetProcAddress( hDll, listFuncName );
#else // POSIX
void* handle = dlopen( NULL, 0 );
mCreateHandler = dlsym( handle, createFuncName );
mDestroyHandler = dlsym( handle, destroyFuncName );
mGetHandlerTypes = dlsym( handle, listFuncName );
dlclose( handle );
#endif // !POSIX
So the key here is that I'm calling a function in my own main program using dynamic linking.
( Why I do this is beyond the scope of the question, but short answer: this is a plugin architecture, but I have some standard plugins that are linked directly into the main binary - but I still want to load them through the same plugin loading interface. E.g. for the built-in plugins I load them by passing in the current executable as the source of the plugin interfaces. )
Here is the problem: the linker doesn't know I'm going to need these functions and doesn't link them in.
How do I force these functions to be linked in? For a dynamic lib, exporting them is enough. But for an exe, even dll exported function are deleted by the linker.
I know I can probably force linking by making the main binary assign these function addresses to something or some other similar hack. Is there a right way to do this?
@UPDATE: So I have a solution that works - but it sure is ugly on the inside. Still looking for a better way.
So I have to somehow define the symbols I need in the object that loads the built-in interfaces. I don't think there is a way to force the linker to link in a symbol otherwise. E.g. There is no way that I know of to build a library with a function that is always linked wether it looks needed or not. This is entirely at the discretion of the link step for the executable.
So in the executable I have a macro that defines the built-in interfaces I need. Each built-in plugin has a prefix to all of its interface functions so, at the top of the file I do:
DEFINE_BUILT_IN_PLUGIN( PluginOne )
DEFINE_BUILT_IN_PLUGIN( PluginTwo )
This will force the definitions of the functions I need. But the macro to do this is so ugly that I'm filled with feelings of rage and self doubt ( I've removed the trailing slashes from the macro for readability ):
#define FORCE_UNDEFINED_SYMBOL(x)
void* _fp_ ## x ## _fp =(void*)&x;
if (((ptrv) _fp_ ## x ##_fp * ( rand() | 1 )) < 1 )
exit(0);
#define DEFINE_BUILT_IN_PLUGIN( PREFIX )
extern "C"
{
KSrvRequestHandler* PREFIX ## CreateRequestHandler( const char* name );
bool PREFIX ## DestroyRequestHandler( KSrvRequestHandler* handler );
const char** PREFIX ## ListRequestHandlerTypes();
}
class PREFIX ## HandlerInterfaceMagic
{
public:
PREFIX ## HandlerInterfaceMagic()
{
FORCE_UNDEFINED_SYMBOL( PREFIX ## CreateRequestHandler );
FORCE_UNDEFINED_SYMBOL( PREFIX ## DestroyRequestHandler );
FORCE_UNDEFINED_SYMBOL( PREFIX ## ListRequestHandlerTypes );
}
};
PREFIX ## HandlerInterfaceMagic PREFIX ## HandlerInterfaceMagicInstance;
Since the compiler is an optimizing genuis, in FORCE_UNDEFINED_SYMBOLS I'm going to great lengths to trick the compiler into linking an unreferenced function. That macro only works inside a function. So I have to create this bogus Magic class. There must be a better way.
Anyway - it does work.