Этот вопрос тесно связан с dlopen a dynamic library from a static library linux C++, но содержит дополнительную сложность (и использует C++ вместо C):dlopen динамической библиотеки из статической библиотеки, когда динамическая библиотека использует символы статической одной
У меня есть приложение, которое ссылается на статическую библиотеку (.a), и эта библиотека использует функцию dlopen для загрузки динамических библиотек (.so). Кроме того, динамические библиотеки вызывают функции, определенные в статическом.
Есть ли способ скомпилировать это, не связывая динамические библиотеки со статическим или наоборот?
вот что я пытался до сих пор, немного изменив пример из связанный с этим вопрос:
app.cpp:
#include "staticlib.hpp"
#include <iostream>
int main()
{
std::cout << "and the magic number is: " << doSomethingDynamicish() << std::endl;
return 0;
}
staticlib.hpp:
#ifndef __STATICLIB_H__
#define __STATICLIB_H__
int doSomethingDynamicish();
int doSomethingBoring();
#endif
staticlib.cpp :
#include "staticlib.hpp"
#include "dlfcn.h"
#include <iostream>
int doSomethingDynamicish()
{
void* handle = dlopen("./libdynlib.so",RTLD_NOW);
if(!handle)
{
std::cout << "could not dlopen: " << dlerror() << std::endl;
return 0;
}
typedef int(*dynamicfnc)();
dynamicfnc func = (dynamicfnc)dlsym(handle,"GetMeANumber");
const char* err = dlerror();
if(err)
{
std::cout << "could not dlsym: " <<err << std::endl;
return 0;
}
return func();
}
staticlib2.cpp:
#include "staticlib.hpp"
#include "dlfcn.h"
#include <iostream>
int doSomethingBoring()
{
std::cout << "This function is so boring." << std::endl;
return 0;
}
dynlib.cpp:
#include "staticlib.hpp"
extern "C" int GetMeANumber()
{
doSomethingBoring();
return 1337;
}
и построить:
g++ -c -o staticlib.o staticlib.cpp
g++ -c -o staticlib2.o staticlib2.cpp
ar rv libstaticlib.a staticlib.o staticlib2.o
ranlib libstaticlib.a
g++ -rdynamic -o app app.cpp libstaticlib.a -ldl
g++ -fPIC -shared -o libdynlib.so dynlib.cpp
Когда я запускаю его с ./app
я получаю
could not dlopen: ./libdynlib.so: undefined symbol: _Z17doSomethingBoringv
and the magic number is: 0
Когда речь идет о статических библиотеках в среде POSIX, только сшивание участия, когда ваше приложение ссылка с статической библиотекой. Сама статическая библиотека не связана. Фактически, статическая библиотека представляет собой не что иное, как архив объектных файлов, которые связаны в вашем приложении, как и любой другой объектный файл. Кроме того, целью использования 'dlopen' является загрузка модуля во время выполнения, поэтому вам не нужно связываться с модулями, которые вы' dlopen'. –
Спасибо за разъяснение, я довольно новичок в мире ссылок. Однако остается мой вопрос: как сделать символы, определенные в этом архиве (или в любом объектном файле) доступными для динамически загружаемой библиотеки? – Johanna
О, кстати, помните, что [C++ использует * name mangling *] (http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B). Это означает, что символ 'GetMeANumber' не будет называться как в объектном файле. Чтобы пропустить манипулирование именами, вы должны сделать функцию 'extern 'C" ', как в' extern' C "int GetMeANumber() {...}' –