Here is an example of registry based dynamic loading. First, the plugin: //////////////////////////////////// // test plugin thing println "Hello Plugin tp init"; gen setup(x:string) : int = { println$ "Module tp setup with " + x; return 0; }
proc entry() { println$ "Module tplug entry"; } export fun setup of (string) as "tplug_setup"; export fun entry of (unit) as "tplug_entry"; //////////////////////////////// Now, to test the registry, I'm going to do an *ordinary* plugin load, then I'm going to STEAL the antry points from it and add them to the registry. Then I will load this artificially created module. This is NOT static linking! But it shows what has to be done. ////////////////////////////////// // First we do a dynamic load of the plugin. // Note this is using lower level routines. ////////////////////////// STANDARD DYNAMIC LOAD var linst = Dynlink::init_lib("tplug"); println$ "tplug instance created"; var sresult = Dynlink::func1[int,string] (linst, "tplug_setup") ("tplug setup string"); C_hack::ignore (sresult); var entry = Dynlink::proc0 (linst, "tplug_entry"); entry; println$ "Plugin run"; ////////////////// POPULATE REGISTRY // Now, grab the entry points and make a module // in the registry using them. var lib = Dynlink::get_library linst; var tfc = Dynlink::get_thread_frame_creator_as_address lib; var star = Dynlink::get_start_as_address lib; Dynlink::add_symbol ("silly","silly_create_thread_frame",tfc); Dynlink::add_symbol ("silly","silly_flx_start",star); var setup=Dynlink::raw_dlsym(lib,"tplug_setup"); var entrypoint =Dynlink::raw_dlsym(lib,"tplug_entry"); Dynlink::add_symbol("silly","silly_setup",setup); Dynlink::add_symbol("silly","silly_entry",entrypoint); ///////////////////// RUN FROM REGISTRY // And now try to run it. var linst2 = Dynlink::init_lib("silly"); println$ "Silly instance created?"; var sresult2 = Dynlink::func1[int,string] (linst2, "silly_setup") ("silly setup string"); C_hack::ignore (sresult2); var entry2 = Dynlink::proc0 (linst2, "silly_entry"); entry2; println$ "Silly Plugin run"; ////////////////////////////// Hello Plugin tp init tplug instance created Module tp setup with tplug setup string Module tplug entry Plugin run Hello Plugin tp init Silly instance created? Module tp setup with silly setup string Module tplug entry Silly Plugin run //////////////////////////////////////// the important thing to note is that the code to run from DLL loaded from the file system is *identical* to the code used to run code from the registry. In otherwords, the use of the registry is **transparent** to the program. The registry is stored in the garbage collector. There is only one (per garbage collector!). (The current access is NOT thread safe! That will be fixed). This has important consequences, in particular it allows HIJACKING. For example consider an actual DLL like fdoc2html loaded by the webserver. It loads flx2html, which loads cpp2html. If the webserver "preloads" cpp2html, then flx2html will use the preloaded version in the registry rather than loading an actual DLL. This will work even if flx2html is dynamically loaded. Now, for static linking what we need to do is conditionally include the Felix code calling "add_symbol". It will get the machine addresses of statically linked symbols from C using something like this: header fred = 'extern "C" void fred()'; const fred:address = "(void*)fred"; Dynlink::add_symbol ("somelib","fred",fred); We can actually put this stuff in our programs inside a function, and if we don't call that function it will just evaporate. So all we need to arrange is to call that function if, and only if, we're static linking. And of course we have to actually make the plugin static link library available to "flx". AFAIK there's no way to tell if one is static linking in Felix. In C we know, because FLX_STATIC_LINK macro is set. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Own the Future-Intel® Level Up Game Demo Contest 2013 Rise to greatness in Intel's independent game demo contest. Compete for recognition, cash, and the chance to get your game on Steam. $5K grand prize plus 10 genre and skill prizes. Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language