Antoninus said:
...
[dlopen on library that uses symbols in main program fails]
Did you link the main program with -rdynamic? If not, only
the symbols the external library knows it needs at link-time
will be exported.
That did the trick, thanks a lot for the quick answer!
While it is fortunate the answer worked for you, it was by pure
luck since there is no way to actually know what system you are
working on. You did not provide enough information to really
provide a correct answer.
The "-rdynamic" flag may not have been available on the compiler
you were using. You may have needed to find a flag that served a
similar function.
There may have been no way of accomplishing this from your
compiler, and you would have then needed to read the
documentation on your linker to find out how to build a binary
properly to give you similar properties.
Or, you may have been required to export those parts of your code
that is needed by the dynamically loaded library into a different
library that the dynamically loaded library can link against.
These issues may not feel relevant to you now, but they should be
kept in mind for when you change jobs and you find yourself needing
to something very similar on a very alien development environment.
As you can see from the explanations provided, none of the solutions
(including the one that apparently worked for you) had anything to
do with C programming or the C language.
A technique that is sometimes used in C development to get around
such issues without linker tricks is to use explicit symbol
registration APIs. After using magic to load in a plugin, the
plugin should provide an entry point to accept symbol registration.
Let's call this entry point "init_symbols()".
struct external_symbols g_es;
struct internal_symbols g_is;
const struct internal_symbols *
init_symbols (const struct external_symbols *s)
{
g_es = *s;
return &g_is;
}
After the main program calls init_symbols, the plugin can refer
to g_es to get to the symbols exported by the main program, and
the main program can refer to the return value of the function
to refer to symbols exported by the plugin.
struct external_symbols {
int (*foo)(void);
int (*bar)(void);
};
struct internal_symbols {
int (*stage1)(void);
int (*stage2)(void);
};
Of course, the actual magic for loading a plugin and getting
to the entry point varies depending on the system (but in your
case they seem to presently be dlopen and dlsym).
-- James