Creating a module system (dynamic loading) in C

前端 未结 9 1971
故里飘歌
故里飘歌 2020-12-12 12:53

How would one go about loading compiled C code at run time, and then calling functions within it? Not like simply calling exec().

EDIT: The the program loading the

9条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-12 13:58

    See this question has been answered but thought others interested in this topic may appreciate a cross platform example from an old plugin based application. The example works on win32 or linux, and seaches for and calls a function called 'constructor' in the dynamically loaded .so or .dll specified in the file argument. The example is in c++ but the procedures should be the same for c.

    //firstly the includes
    #if !defined WIN32
       #include 
       #include 
    #else
       #include 
    #endif
    
    //define the plugin's constructor function type named PConst
    typedef tcnplugin* (*PConst)(tcnplugin*,tcnplugin*,HANDLE);
    
    //loads a single specified tcnplugin,allmychildren[0] = null plugin
    int tcnplugin::loadplugin(char *file) {
        tcnplugin *hpi;
    #if defined WIN32               //Load library windows style
        HINSTANCE hplugin=LoadLibrary(file);
        if (hplugin != NULL) {
                PConst pinconstruct = (PConst)GetProcAddress(hplugin,"construct");
    #else                                   //Load it nix style
        void * hplugin=dlopen(file,RTLD_NOW);
        if (hplugin != NULL) {
                PConst pinconstruct = (PConst)dlsym(hplugin,"construct");
    #endif   
                if (pinconstruct != NULL) { //Try to call constructor function in dynamically loaded file, which returns a pointer to an instance of the plugin's class
                        hpi = pinconstruct(this, this, hstdout);
                } else {
                        piprintf("Cannot find constructor export in plugin!\n");
                        return 0;
                }
        } else {
                piprintf("Cannot open plugin!\n");
    #if !defined WIN32
                perror(dlerror());
    #endif
                return 0;
        }
        return addchild(hpi); //add pointer to plugin's class to our list of plugins
    }
    

    Might also be mentioned that if the module who's functions you wish to call is written in c++ your must declare the function with extern "C" such as:

    extern "C" pcparport * construct(tcnplugin *tcnptr,tcnplugin *parent) {
        return new pcparport(tcnptr,parent,"PCPARPORT",0,1);
    }
    

提交回复
热议问题