Я бы не стал винить QLibrary
: func
просто занимает много времени при первом вызове. Могу поспорить, что у вас будут идентичные результаты, если вы разрешите его адрес с помощью кода для конкретной платформы, например dlopen
и dlsym
в Linux. QLibrary
на самом деле мало что делает, кроме упаковки API платформы. Нет ничего конкретного, что могло бы замедлить первый звонок.
Есть некоторый запах кода при выполнении файлового ввода-вывода в конструкторах предположительно универсальных классов: знают ли пользователи класса, что конструктор может блокировать дисковый ввод-вывод и, следовательно, в идеале не должен вызываться из потока GUI ? Qt делает выполнение этой задачи асинхронно довольно простым, так что я, по крайней мере, постараюсь быть таким хорошим:
class MyClass {
QLibrary m_lib;
enum { my_func = 0, other_func = 1 };
QFuture<QVector<FunctionPointer>> m_functions;
my_type my_func() {
static my_type value;
if (Q_UNLIKELY(!value) && m_functions.size() > my_func)
value = reinterpret_cast<my_type>(m_functions.result().at(my_func));
return value;
}
public:
MyClass() {
m_lib.setFileName("Path_to_lib.dll");
m_functions = QtConcurrent::run{
m_lib.load();
if (m_lib.isLoaded()) {
QVector<QFunctionPointer> funs;
funs.push_back(m_lib.resolve("_func_from_dll"));
funs.push_back(m_lib.resolve("_func2_from_dll"));
return funs;
}
return QVector<QFunctionPointer>();
}
}
void use() {
if (my_func()) {
char buf1[50] = {0}, buf2[50] = {0};
QElapsedTimer timer;
timer.start();
auto result1 = my_func()(buf1);
qDebug() << "first call took" << timer.restart() << "ms";
auto result2 = my_func()(buf2);
qDebug() << "second call took" << timer.elapsed() << "ms";
}
}
};