|
|
Shared objects may be created from C++ source as well as from C source. The foregoing discussion of creating and using C shared objects applies to C++ shared objects also, with two limitations:
An example would be this:
so.h: #include <stdio.h>Since this kind of duplicate construction is probably not what was intended, such use of same-named file scope objects is best avoided. (The -Bsymbolic option can be used to create two separate spaces for the objects, but this probably is not what was intended either.)class A { public: A(const char* s) { printf("ctor %s, object %x\n", s, this); } };
so1.C: #include "so.h"
A a("from so1.C");
so2.C: #include "so.h"
A a("from so2.C");
int main() { }
$ CC -G -KPIC -o libx.so so1.C $ CC so2.C libx.so $ a.out ctor from so1.C, object 8049840 ctor from so2.C, object 8049840
The options to the CC command to create and locate shared objects are the same as the options to the cc command. The following command, for example, will create a shared object named libfoo.so from two C++ source files:
$ CC -G -KPIC -o libfoo.so function1.C function2.C
To avoid dangling references, you should ensure that all templates referenced within a library are instantiated within the library.
Unlike an archive library, with a shared object the linker cannot determine what subset of functions and objects within a library are actually needed by the program, therefore, all the static constructors (destructors) in the shared object will be executed when the shared object is loaded (unloaded). The static constructors will be called in thereverse of the order the object files appear on the command line used to create the object. For example, given the following command line,
$ CC -G function1.o function2.o function3.othe static constructors will be called in the order function3.o function2.o function1.o. When the object is unloaded, the static destructors will be called in the reverse order of the calls to the static constructors, that is, in the order the object files appear on the command line.
When multiple C++ shared objects are loaded, if shared object a depends on shared object b, the static constructors in shared object b will be executed first. There is no guarantee of any ordering of calls to static constructors between unrelated shared objects. When the program exits, the static destructors are called in the reverse order of the calls to the static constructors. If dlclose(3C) is used to explicitly close a shared object, static destructors may be executed out-of-sequence with respect to other static destructors in shared objects that are still open. (The ISO C++ standard considers that dynamic libraries are outside the scope of the standard, which means that behavior such as this does not constitute a violation of the standard.)
The dynamic linker does not demangle any names in the diagnostics it produces. (See
``C++ external function name encoding''.)
If a diagnostic appears somewhat cryptic:
$ a.out dynamic linker: a.out: symbol not found: g__Fv Killedcapture the standard error output and demangle it with the c++filt(1C++) filter program:
$ a.out 2>/var/tmp/a.out.err Killed $ c++filt </var/tmp/a.out.err dynamic linker: a.out: symbol not found: g(void)