Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 动态共享库加载框架_C_Linux_Ubuntu_Shared Libraries - Fatal编程技术网

C 动态共享库加载框架

C 动态共享库加载框架,c,linux,ubuntu,shared-libraries,C,Linux,Ubuntu,Shared Libraries,我正在使用一个遗留的C库,它可以通过编写用户定义的函数然后重新编译源代码来进行扩展。我希望避免编译需求,而是使用函数对其进行一次扩展(请参见下面的伪代码): 此功能的实现方式如下: VARIANT_TYPE CallSharedLibFunction(const char* library_name, const char* funcname, const char *params, const char* return_type){ // parse arguments and get dat

我正在使用一个遗留的C库,它可以通过编写用户定义的函数然后重新编译源代码来进行扩展。我希望避免编译需求,而是使用函数对其进行一次扩展(请参见下面的伪代码):

此功能的实现方式如下:

VARIANT_TYPE CallSharedLibFunction(const char* library_name, const char* funcname, const char *params, const char* return_type){
// parse arguments and get data types and count
// initiate variable of data type indicated by return_type, to hold returned variable

/* this is the part I need help with */
// lptr = LoadSharedLibrary(library_name);
// funcptr = GetFunctionAddress(lptr, funcname);

// call function and pass it arguments
retvalue = funcptr(param1, param2, param3);

// wrap up returned value in the VARIANT_TYPE
VARIANT_TYPE ret;
setVariantValue(ret, retvalue, return_type);

return ret;
}

注意:尽管有“Windows声音”名称(VARIANT_TYPE、LoadSharedLibrary和GetFunctionAddress),我还是在Linux(Ubuntu 9.10)上开发。理想情况下,我希望库加载实现是跨平台的(因为我使用的是ANSIC代码)。但是如果我必须选择一个平台,那就是Linux平台


如果有人能告诉我如何调用任意共享库中的函数(理想情况下,是以跨平台的方式——在Linux上不行),以便实现上述函数,我将不胜感激。

对于Linux/POSIX,您可以使用
函数系列在运行时加载共享库,查找符号地址,等等


如果您想添加一个库依赖项,以使可加载代码的使用变得更容易(和更可移植),请查看glib。

您可能需要查看、dlsym和类似的函数。这些在POSIX上工作(linux、OSX、win32+cygwin等)

使用dlopen(),可以打开共享库。LoadSharedLibrary可以是dlopen()的包装器。GetFuncPtr()函数可以是dlsym()的包装器。您可以做的是围绕dl*()函数编写代码,使其具有健壮性—就像执行一些错误检查一样。您可能还希望在共享库中定义一个接口,即“导出”支持的函数的结构。通过这种方式,您可以获得方法列表,而无需读取elf文件

还有

下面是一个关于用法的快速示例:

void* LoadSharedLibrary(const char* name)
{
   return dlopen(name, RTLD_LOCAL | RTLD_LAZY);
}    

void* GetFunctionAddress(void* h, const char* name)
{
   return dlsym(h, name);
}

const char** GetFunctionList(void* h)
{
   return (char**)dlsym(h, "ExportedFunctions");
}

// Declare a variable to hold the function pointer we are going to retrieve.
// This function returns nothing (first void) and takes no parameters (second void).
// The * means we want a pointer to a function.
void (*doStuff)(void);

// Here we retrieve the function pointer from the dl.
doStuff = GetFunctionAddress(h, "doStuff");

// And this how we call it. It is a convention to call function pointers like this.
// But you can read it as 'take contents of the doStuff var and call that function'.
(*doStuff)();

使用dlopen/dlsym并使用-fPIC/fPIC代码编译它

嗨,Johan,这看起来像是我要找的(可惜我不能找到你的答案!)。然而,你能解释一下吗,(对我来说有点神秘):(void*)(&doStuff)=GetFunctionAddress(h,“doStuff”);(*多斯塔夫)();