如何使用2 C LIB导出相同函数名称[重复
题
以下问题的重复: C功能冲突
嗨,在我当前的项目中,我必须使用某种接口lib。函数名称由此接口给出,此函数的作用是开发人员选择。据我所知,一个项目应使用此功能,并且在编译时,您选择了LIB及其功能。我尝试做的是同时使用现有的LIB和我的LIB,并将其称为Mein函数:
其他Lib:
int function1 (int a) {
// do something
}
mylib:
int function1 (int a) {
//my code here
otherlib::function1(a);
}
问题是我无法访问其他LIB,而另一个LIB没有任何名称空间。我已经尝试了
namespace old {
#include "otherlib.h"
}
然后通过我的函数中的old :: function1调用旧函数。只要它是唯一的标题文件,就可以使用。 LIB将其符号导出到全球空间中。也有类似的东西
namespace new {
function1 (int a) {
::function1(a);
}
}
不起作用。最后但并非最不重要的一点是我尝试了ifdefs并定义了建议 这里
但是我没有成功。
有什么想法解决这个问题吗?提前致谢。
编辑:我既不能使用旧的lib,也不可以使用两个液体的项目。
EDIT2:至少旧的lib是静态的。
解决方案
C中的名称空间使用库名称求解,例如:
libfoo-> foo_function1
libbar-> bar_function1
这些前缀是实际的名称空间。因此,如果您写Libbar
int bar_function1(int a) {
function1(a);
}
这是解决问题的方法。
C有名称空间---他们只是称为前缀;)
另一个选择是通过库的动态加载来执行各种肮脏的技巧:
h1=dlopen("libfoo.so")
foo_function1=dlsym(h1,"function1")
h2=dlopen("libbar.so")
bar_function1=dlsym(h2,"function1")
其他提示
似乎另一个LIB是C,您的代码为C ++。您可能会遇到一个杂乱无章的问题(C ++编译器构造了符号 - 在符号名称中添加额外的内容会区分超载等)。
如果库是纯C,您可以尝试:
extern "C" { // disable mangling of symbol names in the block
#include "otherlib.h"
}
namespace new_lib { // new is a reserved word
int function1( int a ) {
::function1(a);
}
}
我没有尝试过。还考虑提供您收到的错误消息。
另一个选项是(如果库是动态的)动态加载LIB并调用该功能。在Linux(我不知道Windows)中,您可以使用Dlopen打开库,DLSYM获得符号并调用:
// off the top of my head, not tried:
int function1( int a )
{
int (*f)(int); // define the function pointer
void * handle = dlopen( "library.so" );
f = dlsym( handle, "function1" );
f( a ); // calls function1(a) in the dynamic library
}
在这种情况下,由于您没有链接到库,您不会得到符号冲突,但是话又说回来,它仅适用于动态库,并且对于常规使用情况非常麻烦。
更新
如果您的用户不会直接使用“其他Lib”(他们不包括标题),并且他们只能是C ++,那么第一种方法是可能的(即使阅读可怕):
// newlib.h
namespace hideout {
int f( int a );
}
using namespace hideout; // usually I would not put this on the header
// newlib.cpp
extern "C" { // if otherlib is C, else remove this line
#include "otherlib.h"
}
namespace hideout {
int f( int a ) { return ::f( a*2 ); }
}
// main.cpp
#include "newlib.h"
int main()
{
std::cout << f( 5 ) << std::endl;
}
它是如何工作的?用户代码只会看到函数1的声明(示例f()中),因为它们不包括 其他Lib.H. 。在您的编译单元内,您会看到这两个声明,但您可以通过使用名称空间来区分。标题中的使用语句不会打扰您,因为您在CPP中完全有资格。用户 main.cpp 将仅包括您的标题,因此编译器只会看到 藏身处:: f, ,并且由于使用语句而将其视为任何地方。链接器将毫无问题,因为C ++符号被弄脏以识别真实名称空间:
// g++ 4.0 in macosx:
00002dbe T __ZN7hideout9function1Ei // namespace hideout, function1 takes int, returns int
00002db0 T _function1
如果用户代码同时包括您的标题和 其他Lib.H 然后,它必须限定要调用哪个功能。
如果您真的很绝望,则可以编写使用名称空间或前缀的包装库,也可以允许使用DLSYM技巧。此包装库将需要动态链接(以避免符号冲突)。然后,动态库可以安全地将旧的静态库嵌入其中。只需确保在制作动态包装库时不要从静态库中导出符号。
您无法在链接时间解决此问题,因此您需要在运行时通过动态库解决它。这些功能的符号基本上是在库生成后烘烤的。如果两个库导出相同的符号,则它们都不能在静态上链接。