保持共享库不使用自己的导出

时间:2016-03-03 16:14:29

标签: c++

晚上好,

我有一个库导入另一个导出函数的库,我们称之为foo()。我希望我的库充当其他库的包装器。这意味着,我希望我的库导出一个函数foo(),它在内部调用另一个库中的函数foo()。像这样:

myfoo.hpp:

__attribute__((visibility("default"))) void foo();  //my foo() export

myfoo.cpp:

#include "myfoo.hpp"
#include "wrapperfoo.hpp"

void foo()
{
   wrapperfoo();
}

wrapperfoo.cpp:

#include "wrapperfoo.hpp"
#include "theotherapifoo.hpp"

void wrapperfoo()
{
   ::foo();  //PROBLEM!! This seems to call my own exported foo from myfoo.hpp!!!
}

问题是两个动态库都链接到可执行文件中,尽管wrapperfoo.cpp不包含myfoo.hpp,但我的包装函数似乎递归地反复调用我自己的导出foo函数!

我该怎么做才能防止这种情况发生并访问其他库foo()?

1 个答案:

答案 0 :(得分:0)

一种解决方法是使用dlopen()或类似方式动态链接库。

#include <cstring>
#include <dlfcn.h>
#include <stdexcept>

struct OriginalLibrary {
    using FunPtr = void(*)();
    OriginalLibrary()
        : m_lib([] {
                if (void * const lib = dlopen("libdl.so", RTLD_NOW))
                    return lib;
                throw std::runtime_error(dlerror());
            }())
        , m_foo(getFunSym("foo"))
    {}
    ~OriginalLibrary() noexcept { dlclose(m_lib); }

    FunPtr getFunSym(char const * const name) {
        if (void * const sym = dlsym(m_lib, name)) {
            FunPtr f;
            // Assuming function and data pointers are of
            // same size and binary-compatible on your arch:
            std::memcpy(&f, &sym, sizeof(f));
            return f;
        }
        throw std::runtime_error(dlerror());
    }

    void * const m_lib;
    void (* m_foo)();
};

// WARNING! Global symbol! (you might want to solve this in some other manner)
OriginalLibrary original;

void foo() { return original.m_foo(); }