Принятый ответ с приведенной ниже перегрузкой действительно не запускает -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.
Обычное решение вашей проблемы - объявить таблицу указателей на функции, выполнить один 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.
Вы можете обернуть свое приложение другим приложением, которое сначала проверяет наличие всех необходимых библиотек, и если чего-то не хватает, то выдает ошибку, но если все в порядке, оно запускает реальное приложение.
Ваша проблема в том, что разрешение неразрешенных символов выполняется очень рано - в Linux я считаю, что символы данных разрешаются при запуске процесса, а символы функций выполняются лениво. Следовательно, в зависимости от того, какие символы у вас остались неразрешенными, и от того, какой тип статической инициализации вы выполняете - у вас может не быть шанса войти с вашим кодом.
Я предлагаю создать приложение-оболочку, которое задерживает возврат строка кода / ошибки «невозможно загрузить разделяемые библиотеки», а затем преобразует это во что-то более значимое. Если это общий вариант, его не нужно будет обновлять каждый раз, когда вы добавляете новую общую библиотеку.
В качестве альтернативы вы можете запустить сценарий оболочки ldd
, а затем проанализировать вывод,