vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| After much effort I was able to create C++ loadable modules for AIX (using xlC). This is how it's done: The problem: We have a main program 'main' containing a class A with virtual functions. We want to write a module 'module.so' to be loaded using dlopen which will implement a class B, a subclass of A, which will implement some or all of its virtual functions. Most importantly, the module needs to access symbols from the main program. The solution: The solution is very straightforward on linux, but gave me some trouble on AIX. First of all, if we want the module to access main's symbols, we must use the runtime linker. This is already enabled for the module if we link with the -G flag, but we also need to enable it for the main program using the -brtl flag. By the way, enabling RTL on the main program when using g++ causes dlopen to SIGSEGV. I don't know why. Now, in AIX we need to explicitly export the symbols from the main program. !!! -bexpall WILL NOT WORK because (as the ld man page says) it does not export symbols beginning with an underscore, as do all the symbols representing operators, constructors and destructors in a C++ program. Using -bexpall will probably cause dlopen to fail because the runtime-linker will not be able to resolve all symbols. So we must create an export file. This is simply done with the CreateExportList utility which is given all of the main program's objects, and creates an export file. So we compile as follows: main: CreateExportList export_file $(objects) xlC -Wl,brtl,-bE:export_file $(objects) -o main module: xlC -qmkshrobj -Wl,-G,-bnoentry module.C -o module.so The -qmkshrobj flag is not always necessary - it does the same thing CreateExportList does and passes the export list to the linker, but we cannot use it for the main program as it also sets linker options unique to shared objects. In any case, if we want to export all symbols in the module we need to use it. The rest is trivial: module.c: class B : public A { ... } extern "C" // this is necessary for dlsym to work A *instance() { return new B; } main.c: ... void *handle = dlopen("module.so", RTLD_NOW | RTLD_GLOBAL); A* (*instance)() = (A*(*)())dlsym(handle, "instance"); A *my_obj = instance(); |
| |||
| Ron wrote: > First of all, if we want the module to access main's symbols, we must > use the runtime linker. Or use "." imports to your module. This special symbol means that the symbol is provided by (exported from) the main application. > Now, in AIX we need to explicitly export the symbols from the main > program. If you're doing dynamic loading, yes. > !!! -bexpall WILL NOT WORK because (as the ld man page says) it does > not export symbols beginning with an underscore, as do all the symbols > representing operators, constructors and destructors in a C++ program. > Using -bexpall will probably cause dlopen to fail because the > runtime-linker will not be able to resolve all symbols. Correct. Using the linker on current AIX levels allows the -bexpfull option, which should take care of this issue. > The -qmkshrobj flag is not always necessary - it does the same thing > CreateExportList does and passes the export list to the linker, but we > cannot use it for the main program as it also sets linker options > unique to shared objects. Correct. -qmkshrobj (or -G which now apparently implies -qmkshrobj) are _always_ required for building C++ modules with VAC++. It is _never_ required for building a VAC++ main application. > In any case, if we want to export all > symbols in the module we need to use it. When you use this option, the default is to export every defined symbol from the module. -- Gary R. Hook / AIX PartnerWorld for Developers / These opinions are MINE __________________________________________________ ______________________ |
| |||
| "Gary R. Hook" <nospam@nospammers.net> wrote in message news:<4xpDb.908$Ap5.335929443@newssvr11.news.prodi gy.com>... > > > First of all, if we want the module to access main's symbols, we must > > use the runtime linker. > > Or use "." imports to your module. This special symbol means that > the symbol is provided by (exported from) the main application. > Can you explain how to do this? Also, are there any disadvantages to using the runtime linker? |
| ||||
| Ron wrote: > "Gary R. Hook" <nospam@nospammers.net> wrote in message news:<4xpDb.908$Ap5.335929443@newssvr11.news.prodi gy.com>... > >>>First of all, if we want the module to access main's symbols, we must >>>use the runtime linker. >> >>Or use "." imports to your module. This special symbol means that >>the symbol is provided by (exported from) the main application. > > Can you explain how to do this? Requires an import list and the -BI:<import_file> option. You can use this same file as an export list when building the main application. If you have symbol "foo" exported from main, and your module needs it, the import list look like: foo.exp ------- #!. foo ------- The main app is built with the -bE:foo.exp option, and the module is built with the -bI:foo.exp. Use dump -HTv on the main app and the module to verify, if you like. > Also, are there any disadvantages to using the runtime linker? Speed at exec and load time (some additional overhead). Issues if your application hasn't been architected for gracefully handling multiple instances of symbols. There are a number of folks that use this function successfully, tho, so feel free. -- Gary R. Hook / AIX PartnerWorld for Developers / These opinions are MINE __________________________________________________ ______________________ |