Adrian Chadd wrote: > Maybe one of the goals for squid-3.1 should be runtime loadable dyanmic > modules for "stuff". > > (Although I'm not sure how well that'd work with C++ and its symbol > munging..)
I've some experience in this sense, <http://www.aero.polimi.it/~mbdyn/>. Initially, I was setting a structure containing calls to functions (a la Apache), and lt_dlsym() a pointer to this structure which was cast to extern "C" void * to avoid mangling. Recently, I completely reworked things "the other way 'round" (a la OpenLDAP): the module contains an 'extern "C"' function that is resolved and called by the main program at load time. This function can be passed any C argument, and in the API I defined I also pass pointers to C++ arguments as void *, which eventually need to be cast to their C++ counterparts (purists may dislike casting void *, but it's for the sake of avoiding mangling odds). However, this way modules should need minimal interaction with C++ data structures, since their main purpose would be to register functional objects which later will deal with real data. Something like // functional object that sets a handler; modules will inherit from this class SetMyData { public: // ... virtual void Set(); }; // container for registered objects; the key is a string typedef map<string, SetMyData> MyDataMap; MyDataMap mydatamap; // helper that registers a new functional object bool RegisterSetMyData(const string& s, SetMyData* smd){ return mydatamap.insert(MyDataMap::value_type(s, smd).second; } // the module: class ModuleMyData { // ... }; class ModuleSetMyData { // ... ModuleSetMyData(int argc, char *const argv[]); virtual void Set(); }; // this is the only symbol the module needs to export; call any helper // required to register the functional objects the module wants the main // to use; functional objects may make use of parameters passed like // command-line arguments extern "C" int module_init(int argc, char *const argv[]) { SetMyData* smd = new ModuleSetMyData(argc, argv); RegisterSetMyData("mydataname", smd); } // end of the module The interface is minimal and it's pure C. Of course, it needs reverse linking, so, for example, the function RegisterSetMyData() and any other function the module needs to see must be either exported by the main to the module (the undocumented "-rdynamic" option to gcc), or placed in yet another library that is linked both by the modules and by the main object. Cheers, p. Ing. Pierangelo Masarati OpenLDAP Core Team SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it --------------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Email: [EMAIL PROTECTED] ---------------------------------------
