Как вызвать динамическую библиотечную функцию из c ++? - PullRequest
0 голосов
/ 28 марта 2019

В настоящее время я создаю какую-то систему плагинов.Моя программа пишет код, который затем компилируется (см. Также мой другой вопрос).Полученная (скомпилированная) библиотека затем открывается снова с помощью dlopen.Это позволяет людям самим программировать пользовательские функции в программе.

//Open the compiled library at the specified path
void* handle = dlopen("COMPILEDLIBRARYPATH", RTLD_LAZY);
if (handle == NULL) {
    std::cout << "plugin not found" << std::endl;
}

//Find the function pointer and cast is to std::function (is this good practice??)
std::function<void(float[])> fun = (void (*)(float[]))dlsym(handle, "testFunc");
if (fun == NULL) {
    std::cout << "function not found" << std::endl;
}

float test[3] = {0.0, 0.0, 0.0};
std::cout << "calling plugin" << std::endl;
fun(test);

//Output the result of the call
std::cout << test[0] << " " << test[1] << " " << test[2] << " returned by function" << std::endl;

//Close handle again
if (dlclose(handle) != 0) {
    std::cout << "could not close function" << std::endl;
}

Это работает, как и ожидалось, но также выглядит как хакерское и небезопасное.Я никогда не делал ничего подобного раньше, поэтому я делаю здесь что-нибудь небезопасное?Кроме того, есть ли «лучший» способ сделать это (например, когда мне не нужно снова закрывать ручку)?Может ли это считаться переносимым между операционными системами?

1 Ответ

0 голосов
/ 28 марта 2019

Theres - dlclose(void *handle) для закрытия ручки. Также предпочитайте reinterpret_cast необработанному указателю функции вместо приведения в стиле C к std::function.

dlfcn.h с dlopen и его друзьями является POSIX / UNIX API, поэтому он, вероятно, будет работать в Solaris, Linux, * BSD, macOS и т. Д. В Windows эквивалент dlysym равен GetProcAddress в <windows.h>.

Вот полная статья о динамической загрузке, которая, вероятно, поможет: https://en.wikipedia.org/wiki/Dynamic_loading#In_C/C++

...