Типизации с функцией загрузки функция dlsym


Цель:

Использовать C++0х, чтобы сделать функцию взаиморасположение безопаснее. Проблема в том, что это легко сделать опечатку при наклеивании и вставляя на функции.

Реализация Прототипа:

#define MAKE_WRAPPER(x) static const wrapper<decltype(::x), ::x> x(#x)

namespace {
  template<typename Sig, Sig& S>
  struct wrapper;

  template<typename Ret, typename... Args, Ret(&P)(Args...)>
  struct wrapper<Ret(Args...), P> {
         typedef Ret(*real_func)(Args...);
         real_func f;
         wrapper(const std::string& sym) : f(NULL) {    
                dlerror();
                void *ptr = dlsym(RTLD_NEXT, sym.c_str());
                f = (real_func)ptr;
                if (NULL == f) {
                  std::cerr << "dlsym(): " << dlerror() << std::endl;
                }
                std::cout << "constructing wrapper: " << this << " for: " << sym << "(at " << ptr << ")" << std::endl;
         }

         Ret operator()(const Args&... args) const {
                return f(args...);
         }
  };
}

Пример использования:

extern "C" {
  void glXSwapBuffers(Display *dpy, GLXDrawable drawable) {
         MAKE_WRAPPER(glXSwapBuffers);
         // Do stuff here before making the call to the wrapper
         glXSwapBuffers(dpy, drawable);
  }
}

Вопросы:

  1. Стоит ли это усилий?
  2. Как его можно улучшить?


2028
3
задан 10 августа 2011 в 10:08 Источник Поделиться
Комментарии
1 ответ

[ Я предполагаю, что ваш пример призван вернуть х(dpy, мешочки); а не вызывать саму себя рекурсивно. ]


  1. Это того стоит, если вы пользовались этим думаю.

  2. Печать на СТД::КВЖД - это не обработка ошибок, это ошибки. Выбрать настоящую стратегию обработки ошибок и строго придерживаться его. Аналогично печати с std::соиь надо? Я тоже считаю, что чем меньше библиотечные вызовы есть в конструкторе, тем меньше риски оболочки вызывая себя рекурсивно во время статической инициализации х, которая будет иметь катастрофические последствия.

В POSIX рекомендует следующий способ бросания при работе с функцией типов функция dlsym:

*(void**)&f = dlsym(RTLD_NEXT, sym.c_str());

оператор() можно использовать Perfect переадресации:

Ret
operator()(Args... args)
{
f(std::forward<Args>(args));
}

Обертывание обойдется в два хода или один экземпляр + один ход за аргумент, переданный по значению и одна вперед для ссылочных типов. Он прозрачен для клиента, он или она не должны использовать с std::двигаться , если исходная функция будет уже иметь его обязан. Обратите внимание, что первая скопировать или перенести-значение аргумента должен быть уплачен не важно, что; реальная возможность стоимость упаковки (потенциального) движение, которое приходит после того, чтобы передать аргумент к реальной функции.

По сравнению с ним, используя аргументы как const&... ломается, если обернутом функция пустота фу(т&&);, из-за ведения рушится правил подпись будет недействительной оператор()(Т&);

Возможно, макрос должен взять имя переменной в качестве аргумента, но это не может быть необходимым в зависимости от планируемого использования.

Незначительные любимая мозоль: осмысленные имена. Я бы назвал конструктор параметр символ. Время, необходимое для ввода более трех персонажей, каждый раз-это просто ничтожно мало по сравнению с временем записи и сохранить код. function_type вместо real_func , возможно, тоже.

4
ответ дан 13 августа 2011 в 12:08 Источник Поделиться