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: pierangelo.masarati@sys-net.it
---------------------------------------
Received on Thu Sep 06 2007 - 23:54:03 MDT
This archive was generated by hypermail pre-2.1.9 : Mon Oct 01 2007 - 12:00:05 MDT