gpt4 book ai didi

c++ - dlopen 从静态库中打开动态库,当动态库使用静态库的符号时

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:34:32 65 4
gpt4 key购买 nike

这个问题与dlopen a dynamic library from a static library linux C++密切相关,但包含更复杂的情况(并使用 C++ 而不是 C):

我有一个链接静态库 (.a) 的应用程序,该库使用 dlopen 函数加载动态库 (.so)。此外,动态库调用静态库中定义的函数。

有没有一种方法可以在不将动态库与静态库链接的情况下进行编译,反之亦然?

这是我到目前为止尝试过的,稍微修改了相关问题中的示例:

应用程序.cpp:

#include "staticlib.hpp"
#include <iostream>
int main()
{
std::cout << "and the magic number is: " << doSomethingDynamicish() << std::endl;
return 0;
}

静态库.hpp:

#ifndef __STATICLIB_H__
#define __STATICLIB_H__

int doSomethingDynamicish();
int doSomethingBoring();
#endif

静态库.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();
}

静态库2.cpp:

#include "staticlib.hpp"
#include "dlfcn.h"
#include <iostream>

int doSomethingBoring()

{
std::cout << "This function is so boring." << std::endl;
return 0;

}

动态库.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 manual page :

If the executable was linked with the flag "-rdynamic" (or, synonymously, "--export-dynamic"), then the global symbols in the executable will also be used to resolve references in a dynamically loaded library.

这意味着应用程序要导出其符号以便在动态库中使用,您必须使用 -rdynamic 标志链接您的应用程序。


除了上面描述的问题,还有一个问题和静态库有关:静态库中的 staticlib2.o 未链接。

答案可以在例如this old question ,它告诉您添加 --whole-archive 链接器标志:

g++ -rdynamic -o app app.cpp -L. \
-Wl,--whole-archive -lstaticlib \
-Wl,--no-whole-archive -ldl

关于c++ - dlopen 从静态库中打开动态库,当动态库使用静态库的符号时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26095405/

65 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com