这个问题与在Linux C++中从静态库dlopen动态库密切相关,但包含了进一步的复杂性(并使用C++而非C):
我有一个链接到静态库(.a)的应用程序,该库使用dlopen函数加载动态库(.so)。此外,动态库调用在静态库中定义的函数。
是否有一种方法可以将其编译而不将动态库与静态库链接或反之亦然?
以下是我迄今为止尝试过的,稍微修改了相关问题中的示例:
当我使用
我有一个链接到静态库(.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
dlopen
的目的是在运行时加载模块,因此您不需要链接到您dlopen
的模块。 - Some programmer dudeGetMeANumber
在目标文件中不会被命名为那样。要跳过名称修饰,您必须使函数extern "C"
,如extern "C" int GetMeANumber() { ... }
。 - Some programmer dude