Альтернативы dlsym () и dlopen () в C++

Принятый ответ с приведенной ниже перегрузкой действительно не запускает -Wtype-limit .

template <typename T> inline constexpr
  int signum(T x, std::false_type) {
  return T(0) < x;
}

template <typename T> inline constexpr
  int signum(T x, std::true_type) {
  return (T(0) < x) - (x < T(0));
}

template <typename T> inline constexpr
  int signum(T x) {
  return signum(x, std::is_signed<T>());
}

Для C ++ 11 альтернативой может быть.

template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, int>::type
inline constexpr signum(T x) {
    return T(0) < x;  
}

template <typename T>
typename std::enable_if<std::is_signed<T>::value, int>::type
inline constexpr signum(T x) {
    return (T(0) < x) - (x < T(0));  
}

Для меня это не вызывает каких-либо предупреждений в GCC 5.3.1.

18
задан einpoklum - reinstate Monica 19 January 2016 в 22:36
поделиться

3 ответа

Обычное решение вашей проблемы - объявить таблицу указателей на функции, выполнить один dlsym () для ее поиска и затем вызвать все другие функции через указатель на эту таблицу. Пример (непроверенный):

// libfoo.h
struct APIs {
   void  (*api1)(void);
   void *(*api2)(int);
   long  (*api3)(int, void *);
};

// libfoo.cc
void fn1(void) { ... }
void *fn2(int) { ... }
long fn3(int, void *) { ... }

APIs api_table = { fn1, fn2, fn3 };


// client.cc
#include "libfoo.h"
...
  void *foo_handle = dlopen("libfoo.so", RTLD_LAZY);
  if (!foo_handle) {
     return false;            // library not present
  }
  APIs *table = dlsym(foo_handle, "api_table");
  table->api1();              // calls fn1
  void *p = table->api2(42);  // calls fn2
  long x = table->api3(1, p); // calls fn3

PS Доступ к вашим функциям API по отдельности с помощью dlsym и указателей сам по себе не приводит к повреждению памяти и сбоям. Скорее всего, у вас просто ошибки.

РЕДАКТИРОВАТЬ:
Вы можете использовать ту же технику со сторонней библиотекой. Создайте libdrmaa_wrapper.so и поместите в него api_table . Свяжите оболочку непосредственно с libdrmaa.so .

В основном исполняемом файле dlopen ("libdrmaa_wrapper.so", RTLD_NOW) . Этот dlopen будет успешным, если (и только если) libdrmaa.so присутствует во время выполнения и предоставляет все функции API, которые вы использовали в api_table . В случае успеха один вызов dlsym предоставит вам доступ ко всему API.

32
ответ дан 30 November 2019 в 07:39
поделиться

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

2
ответ дан 30 November 2019 в 07:39
поделиться

Ваша проблема в том, что разрешение неразрешенных символов выполняется очень рано - в Linux я считаю, что символы данных разрешаются при запуске процесса, а символы функций выполняются лениво. Следовательно, в зависимости от того, какие символы у вас остались неразрешенными, и от того, какой тип статической инициализации вы выполняете - у вас может не быть шанса войти с вашим кодом.

Я предлагаю создать приложение-оболочку, которое задерживает возврат строка кода / ошибки «невозможно загрузить разделяемые библиотеки», а затем преобразует это во что-то более значимое. Если это общий вариант, его не нужно будет обновлять каждый раз, когда вы добавляете новую общую библиотеку.

В качестве альтернативы вы можете запустить сценарий оболочки ldd , а затем проанализировать вывод,

-1
ответ дан 30 November 2019 в 07:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: