views:

612

answers:

2

I've a program that implements a plugin system by dinamically loading a function from some plugin_name.so (as usual)

But in turn I've a static "helper" library (lets call it helper.a) whose functions are used both from the main program and the main function in the plugin. they don't have to inter-operate in any way, they are just helper functions for text manipulation and such.

This program, once started, cannot be reloaded or restarted, that's why I'm expecting to have new "helper" functionality from the plugin, not from the main program.

So my questin is.. is it possible to force this "plugin function code" in the .so to use (statically link against?) a different (perhaps newer) version of "helper" than the main program?

How could this be done? perhaps by statically linking or otherwise adding helper.a to plugin_name.so?

Thanks in advance =)!

A: 

If your main program and dynamic library both statically link to helper.a, then you shouldn't need to worry about mixing versions of helper.a (as long as you don't do things like pass pointers allocated in helper.a between the .exe and .so boundaries).

The code required from the helper.a is inserted to the actual binary when you link against it. So when you call into helper.a from the .exe, you will be executing code from the code segment of your executable image, and when you call into helper.a from the .so, you will be executing code from the portion of the address space where the .so was loaded. Even if you're calling the same function inside helper.a, you're calling two different 'instances' of that function depending on whether the call was made from the .exe or the .so.

Nick Meyer
I see. but how could I add the code in libhelper.a to plugin.so at compile time? should I specify something like "gcc -lhelper.a -static" when compiling plugin.so?
conejoroy
If your library is libhelper.a, then pass -L*dir* -lhelper to gcc when compiling plugin.so, where *dir* is the path to libhelper.a. No need to specify -static, that's used when you're creating a static library.
Nick Meyer
This answer is correct only under limited conditions, which aren't stated.
Employed Russian
+1  A: 

Nick Meyer's answer is correct on Windows and AIX, but is unlikely to be correct on every other UNIX platform by default.

On most UNIX platforms, the runtime loader maintains a single name space for all symbols, so if you define foo_helper in a.out, and also in plugin.so, and then call foo_helper from either, the first definition visible to the runtime loader (usually that from a.out) is used by default for both calls.

In addition, the picture is complicated by the fact that foo_helper may not be exported from a.out (and thus may be invisible to runtime loader), unless you use -rdynamic flag, or some other shared library references it. In other words, things may appear to work as Nick described them, then you add a shared library to the a.out link line, and they don't work that way anymore.

On ELF platforms (such as Linux), you have great control over symbol visibility and binding. See description of -fvisibility=hidden and -rdynamic in GCC man page, and also -Bsymbolic in linker man page.

Most other UNIX platforms have some way to control symbol bindings as well, but this is necessarily platform-specific.

Employed Russian