我正在使用遗留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>
答案 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代码
编译它