Как загрузить общий объект в C++?
У меня есть общий объект (так что Linux-эквивалент Windows DLL), который я хотел бы импортировать и использовать с моим тестовым кодом.
Я уверен, что это не так просто;) но это то, что я хотел бы сделать..
#include "headerforClassFromBlah.h"
int main()
{
load( "blah.so" );
ClassFromBlah a;
a.DoSomething();
}
Я предполагаю, что это действительно простой вопрос, но я не могу найти ничего, что бросается в глаза при поиске в Интернете.
4 ответа
Есть два способа загрузки общих объектов в C++
Для любого из этих методов вам всегда понадобится заголовочный файл для объекта, который вы хотите использовать. Заголовок будет содержать определения классов или объектов, которые вы хотите использовать в своем коде.
Статически:
#include "blah.h"
int main()
{
ClassFromBlah a;
a.DoSomething();
}
gcc yourfile.cpp -lblah
Динамически (в Linux):
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("libm.so", RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror(); /* Clear any existing error */
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit(1);
}
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
return 0;
}
* Украдено из справочной страницы Linux dlopen. Процесс под windows или любой другой платформой такой же, просто замените dlopen версией динамического поиска символов для платформ.
Чтобы динамический метод работал, все символы, которые вы хотите импортировать / экспортировать, должны иметь внешнюю связь C.
Здесь есть несколько слов о том, когда использовать статическое, а когда использовать динамическое связывание.
Это зависит от платформы. Чтобы сделать это во время выполнения, в Linux вы используете dlopen, в Windows вы используете LoadLibrary.
Чтобы сделать это во время компиляции, в Windows вы экспортируете имя функции, используя dllexport и dllimport. В linux gcc экспортирует все открытые символы, поэтому вы можете просто ссылаться на них и вызывать функцию. В обоих случаях обычно для этого требуется, чтобы в заголовочном файле было указано имя символа, которое вы затем #include
Затем вы ссылаетесь на библиотеку, используя возможности вашего компилятора.
Вы должны #include любые заголовки, связанные с разделяемой библиотекой, чтобы получить описания таких вещей, как ClassFromBlah. Затем вам нужно связать с.so - как именно это сделать, зависит от вашего компилятора и общей установки, но для g++ что-то вроде:
g++ myfile.cpp -lblah
вероятно будет работать.
Это -l, который связывает архивный файл, такой как libblah.a, или, если вы добавите -PIC к gcc, вы получите файл "разделяемый объект" libblah.so (это компоновщик, который его создает). Однажды у меня было СОЛНЦЕ, и я собирал файлы такого типа. Файлы могут иметь номер редакции, который должен быть точным или большим (код может быть изменен из-за ошибки). но вызов с параметрами должен быть таким же, как и вывод.