重复下列问题:
嗨,在我当前的项目中,我必须使用某种接口库。函数名是由这个接口指定的,这个函数所做的是开发人员的选择。据我所知,一个项目将使用这个函数,当涉及到编译时,您可以选择lib,并选择它的功能。我试图做的是同时使用现有的lib和我的lib,方法是包装另一个库,并在mein函数中调用它:
其他库:
int function1 (int a) {
// do something
}米利卜:
int function1 (int a) {
//my code here
    otherlib::function1(a);
}问题是,我无法访问另一个库,而另一个库没有任何名称空间。我已经试过了
namespace old {
    #include "otherlib.h"
}然后在我的函数中通过old::function 1调用旧函数。只要它只是头文件,它就能工作。lib将它的符号导出回全局空间。也是类似于
namespace new {
    function1 (int a) {
        ::function1(a);
    }
}没起作用。最后但并非最不重要的是,我尝试了ifdefs并定义了建议的here
但我没有成功。
有什么办法解决这个问题吗?提前谢谢。
编辑:我既不能访问旧库,也不能访问项目,这两个库都将在其中使用。
EDIT2:至少旧库是静态的
发布于 2009-03-25 11:42:55
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")发布于 2009-03-25 11:50:14
似乎另一个库是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);
   }
}我还没试过。还可以考虑提供您正在获取的错误消息。
另一个选项是(如果库是动态的)动态加载库并调用函数。在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
}在这种情况下,由于不是针对库进行链接,所以不会出现符号冲突,但同样,它只对动态库有效,对于常规使用来说非常麻烦。
更新
如果您的用户不会直接使用“otherlib”(他们不会包含他们的头),而且他们只会是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;
}它怎麽工作?用户代码只会看到function1的声明(在示例f()中),因为它们不包括therlib.h。在编译单元中,您可以看到这两个声明,但是通过使用命名空间来区分。标题中的using语句不会困扰您,因为您在cpp中完全符合条件。用户main.cpp将只包含您的头,所以编译器只会看到hideout::f,并且会因为using语句而在任何地方看到它。当C++符号标识真正的命名空间时,链接器将没有问题:
// g++ 4.0 in macosx:
00002dbe T __ZN7hideout9function1Ei // namespace hideout, function1 takes int, returns int
00002db0 T _function1如果用户代码同时包含头和其他函数,那么它必须限定要调用的函数。
发布于 2009-03-25 18:27:46
如果您真的很绝望,可以编写一个使用名称空间或前缀或允许使用dlsym技巧的包装库。这个包装器库需要动态链接(以避免符号冲突)。然后,动态库可以安全地将旧的静态库嵌入其中。只需确保在生成动态包装库时不要从静态库导出符号。
https://stackoverflow.com/questions/681200
复制相似问题