2016-03-03 3 views
0

Добрый вечер,Храните общую библиотеку в использовании собственного экспорта.

У меня есть библиотека, которая импортирует другую библиотеку, которая экспортирует функцию, позволяет называть ее 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!!! 
} 

Проблема заключается в том, что обе динамические библиотеки будут связаны в исполняемый файл и мой wrapperfunction, кажется, рекурсивный вызов свою собственную экспортируемую функцию Foo снова и снова, несмотря на wrapperfoo.cpp не включая myfoo.hpp!

Что можно сделать, чтобы это не происходило и доступ к другим библиотекам foo()?

+2

Разве вы не грубо нарушаете правило одного определения? Вы не можете дать двум функциям одно и то же имя. Возможно, я не понимаю ваш вопрос, потому что я очень устал. –

+1

По внешнему виду код заканчивается в замкнутом цикле вызовов. Также почему объект «myfoo» вызывает оболочку оболочки? Разве это не было фактической реализацией? – hauron

+0

Я думаю, вам нужно связать другую библиотеку во время работы. Я не знаю, какие функции использовать, но должен быть способ связать библиотеки во время выполнения и указатели запросов с определенными функциями в загруженной библиотеке. Но при разрешении зависимостей загруженной библиотеки могут возникнуть некоторые проблемы, если вы используете это решение. почему ты хочешь сделать это? – JojOatXGME

ответ

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