动态共享库加载框架

时间:2009-11-10 08:25:52

标签: c linux ubuntu shared-libraries

我正在使用遗留C库,可以通过编写用户定义的函数然后重新编译源来扩展它。我想避免编译要求,而是使用函数将其扩展为ONCE(参见下面的伪代码):

此功能将如下实现:

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)上进行开发。理想情况下,我希望库加载实现是跨平台的(因为我使用的是ANSI C代码)。但是,如果我必须选择一个平台,它必须是Linux平台。

如果有人能够了解如何在任意共享库中调用函数(理想情况下,以跨平台的方式 - 在Linux上失败),我将非常感激,以便我可以实现上述函数。 / p>

3 个答案:

答案 0 :(得分:4)

您可能希望查看dlopen,dlsym和类似函数。这些工作在POSIX(linux,OSX,win32 + cygwin等...)上。

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

还有a nice page about function pointers in C and C++

以下是有关用法的简单示例:

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)();

答案 1 :(得分:2)

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

如果要添加库依赖项以使处理可加载代码更容易(并且更便于移植),请查看glib的module API

答案 2 :(得分:0)

使用dlopen / dlsym以及使用-fPIC / FPIC代码

编译它