如何在运行时加载编译的C代码,然后调用其中的函数?不像简单地调用exec().
编辑:加载模块的程序在C中.
dlopen是要走的路.这里有一些例子:
使用dlopen加载插件:
#include... int main (const int argc, const char *argv[]) { char *plugin_name; char file_name[80]; void *plugin; ... plugin = dlopen(file_name, RTLD_NOW); if (!plugin) { fatal("Cannot load %s: %s", plugin_name, dlerror ()); }
编译以上内容:
% cc -ldl -o program program.o
然后,假设插件的API:
/* The functions we will find in the plugin */ typedef void (*init_f) (); init_f init; typedef int (*query_f) (); query_f query;
在插件中查找init()的地址:
init = dlsym(plugin, "init"); result = dlerror(); if (result) { fatal("Cannot find init in %s: %s", plugin_name, result); } init();
使用另一个函数query(),它返回一个值:
query = dlsym (plugin, "query"); result = dlerror(); if (result) { fatal("Cannot find query in %s: %s", plugin_name, result); } printf("Result of plugin %s is %d\n", plugin_name, query ());
您可以获取完整的例子就行.
在Linux/UNIX中,您可以使用POSIX dlopen
/ dlsym
/ dlerror
/ dlclose
函数动态打开共享库并访问它们提供的符号(包括函数),有关详细信息,请参见手册页.
看到这个问题已得到解答,但认为对此主题感兴趣的其他人可能会欣赏来自旧的基于插件的应用程序的跨平台示例.该示例适用于win32或linux,并在文件参数中指定的动态加载的.so或.dll中调用并调用名为"constructor"的函数.示例是在c ++中,但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 }
可能还会提到,如果要调用的函数模块是用c ++编写的,则必须使用extern"C"声明函数,例如:
extern "C" pcparport * construct(tcnplugin *tcnptr,tcnplugin *parent) { return new pcparport(tcnptr,parent,"PCPARPORT",0,1); }