标签: dlopen

主程序和共享库在__static_initialization_and_destruction_0中初始化相同的静态变量

有谁知道为什么在dlopen()中初始化的库会初始化主程序拥有的静态变量.主程序和共享库都有静态变量的副本,但由于某种原因,共享库重新初始化主程序的静态变量副本并对其进行破坏,在主程序试图破坏它时导致段错误.

这是在符号表中出现错误名称的情况吗?

symbols shared-libraries static-variables segmentation-fault dlopen

8
推荐指数
1
解决办法
4928
查看次数

尝试使用dlopen加载库时未定义的符号

我正在尝试加载一个共享库(插件)我在Linux ARM平台下使用dlopen提供了(封闭源代码).我正在尝试加载这种方式:

void* handle = dlopen(<library_path>/<library_name>, RTLD_NOW);
Run Code Online (Sandbox Code Playgroud)

结果是此消息失败:

Failed to load <library_path>/<library_name>: undefined symbol: <symbol_name>.
Run Code Online (Sandbox Code Playgroud)

我试图用nm查看库内部,但似乎lib被剥离,找不到符号.我也试过使用readelf -s,事实上,我得到了这个结果:

12663: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND <symbol_name>
Run Code Online (Sandbox Code Playgroud)

通过阅读,我得到readelf -s返回所有符号,包括在它引用的库中定义的那些符号.

这个问题的答案对我来说并不完全清楚:这是一个应该在库中的符号,它不存在,因为它是以错误的方式编译的,或者这是一个我应该在其他地方找到的符号?readelf -d的输出似乎表明我提供了所有需要的共享库.可能这个错误与我正在编译可执行文件的方式中的错误有关,或者这与加载程序无关?

另外,我读到了每列的含义,但这些值非常奇怪.你如何解释这个符号描述?为什么地址为0?为什么键入NOTYPE?

c++ linker compilation shared-libraries dlopen

8
推荐指数
2
解决办法
1万
查看次数

何时实际使用 dlopen()?dlopen() 是指动态加载吗?

我浏览了下面的链接,通过它我了解了如何创建和使用共享库。 https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

Step 1: Compiling with Position Independent Code
$ gcc -c -Wall -Werror -fpic foo.c

Step 2: Creating a shared library from an object file
$ gcc -shared -o libfoo.so foo.o

Step 3: Linking with a shared library
$ gcc -L/home/username/foo -Wall -o test main.c -lfoo

Step 4: Making the library available at runtime
$ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
$ ./test
This is a shared library test...
Hello, I am a shared library
Run Code Online (Sandbox Code Playgroud)

但是,我有几个问题:

  1. 在给定的链接中,没有使用打开共享库所需的 dlopen()。这段代码在没有 dlopen() 调用的情况下如何工作?
  2. 何时实际使用 dlopen()?
  3. 我可以在没有 …

linker shared-libraries dynamic-loading dlopen .so

8
推荐指数
1
解决办法
7446
查看次数

为什么这个动态库加载代码与gcc一起使用?

背景:

我发现自己有一个将C++ GNU/Linux应用程序移植到Windows上的令人尴尬的任务.此应用程序执行的操作之一是在特定路径上搜索共享库,然后使用posix dlopen()和dlsym()调用动态地加载它们中的类.我们有充分的理由以这种方式加载,我不会进入这里.

问题:

要使用dlsym()或GetProcAddress()动态发现由C++编译器生成的符号,必须使用extern"C"链接块对其进行解组.例如:

#include <list>
#include <string>

using std::list;
using std::string;

extern "C" {

    list<string> get_list()
    {
        list<string> myList;
        myList.push_back("list object");
        return myList;
    }

}
Run Code Online (Sandbox Code Playgroud)

此代码是完全有效的C++,可在Linux和Windows上的众多编译器上编译和运行.但是,它不能与MSVC一起编译,因为"返回类型无效C".我们提出的解决方法是更改​​函数以返回指向列表而不是列表对象的指针:

#include <list>
#include <string>

using std::list;
using std::string;

extern "C" {

    list<string>* get_list()
    {
        list<string>* myList = new list<string>();
        myList->push_back("ptr to list");
        return myList;
    }

}
Run Code Online (Sandbox Code Playgroud)

我一直在努力为GNU/Linux加载器找到一个最佳解决方案,它既可以使用新函数也可以使用旧的遗留函数原型,或至少检测何时遇到不推荐使用的函数并发出警告.如果代码在他们尝试使用旧库时只是分段,那对我们的用户来说是不合适的.我最初的想法是在调用get_list期间设置一个SIGSEGV信号处理程序(我知道这很icky - 我对更好的想法持开放态度).所以只是为了确认加载一个旧库会发生段错误,我认为我会使用旧的函数原型(返回列表对象)通过新的加载代码(期望指向列表的指针)运行库,令我惊讶的是刚刚工作.我的问题是为什么

下面的加载代码适用于上面列出的两个函数原型.我已经确认它适用于使用gcc版本4.1.2和4.4.4的Fedora 12,RedHat 5.5和RedHawk 5.1.使用带有-shared和-fPIC的g ++编译库,并且可执行文件需要与dl(-ldl)链接.

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <list>
#include <string>

using std::list;
using std::string;

int …
Run Code Online (Sandbox Code Playgroud)

c++ gcc dlopen dlsym

7
推荐指数
1
解决办法
679
查看次数

覆盖用dlopen()加载的DLL中的@executable_path

操作系统是MacOS X,特别是PowerPC G4上的10.5(Leopard),但我在运行10.6的x86上遇到了同样的问题.

我正在编写一个动态加载DLL的应用程序.DLL(让我们称之为foo.dylib)是另一个应用程序的一部分,位于硬盘的其他位置; 我的应用程序以foo.dylib编程方式找到(确切的安置可能会改变,可能用户通过运行的应用程序本身的GUI指定DLL路径).例如,假设我的应用程序位于目录中/Application/MyApp.app/Contents/MacOS,并且foo.dylib恰好位于/Application/OtherApp.app/Contents/MacOS.DLL加载使用dlopen().

现在,事实证明,foo.dylib它本身需要一堆其他DLL,它们位于同一目录中,但我事先并不知道.每个这样的额外DLL都foo.dylib以诸如的路径注册@executable_path/bar.dylib.语义@executable_path是它应该被找到当前进程可执行文件的目录替换.这适用于OtherApp,不适合我:当我打开时foo.dylib,它会尝试加载bar.dylib,并且它会查找/Application/MyApp.app/Contents/MacOS/bar.dylib,这不是正确的目录.

解决方法是将DYLD_FALLBACK_LIBRARY_PATH环境变量设置为/Application/OtherApp.app/Contents/MacOS,但这必须启动我的应用程序之前完成(该环境变量仅由动态链接器读取一次;以编程方式更改其值setenv()putenv()不起作用).这与foo.dylib文件位置的动态发现不兼容.

是否有一种编程方式来覆盖效果@executable_path

macos dynamic-linking dlopen executable-path

7
推荐指数
1
解决办法
3579
查看次数

Solaris进程如何读取自己的符号表?

我有一个Solaris进程,它是一个C++应用程序,由ld几个.so库加载.该应用程序有一个函数,它在调用函数中获取一个返回地址,然后尝试确定所述调用函数的名称.

如果我使用dladdr(3)它,它并不总是把我期望在Dl_info :: dli_sname中看到.看起来它返回的函数名称不是最接近下方或指针值.如果我取指针值并查看输出nm,我可以将该值与我期望的确切函数匹配.

我想知道是否有办法检索进程的符号映射,让它搜索函数名称而不使用dladdr(3).我特别感兴趣的是获得一个符号映射,不仅可以用于可执行文件本身,还可以用于.so它已加载的所有库.

我在Solaris10/SPARC上运行,我正在使用gcc 4.2.x.

谢谢!

c++ solaris loader ld dlopen

7
推荐指数
1
解决办法
944
查看次数

C++:在分离的共享库中实现类方法

我想我可以在共享库中实现类的一部分,只要在使用时加载符号.

myclass.h
---

class C {
void method();
}

main.cpp
---

#include "myclass.h"
int main() {
    //dynamically load mylib.so using dlopen/dlsym/dlclose
        ...
    C *c = new C();
    c->method();
    delete c;
}

mylib.so compiled separately:
====
mylib.cpp
---

#include "mylib.h"
void C::method() {
...
}
Run Code Online (Sandbox Code Playgroud)

这很好用.

但是一旦我完成了使用C :: method(),我想卸载它,所以我可以更改,重新编译并重新加载它而无需重新启动主程序

int main() {
    //dynamically load mylib.so using dlopen/dlsym/dlclose
        ...
    C *c = new C();
    c->method();
    delete c;
    // close the lib, remove the handle...
         ....
    char pause;
    cin << pause; // before …
Run Code Online (Sandbox Code Playgroud)

c++ implementation class dlopen

7
推荐指数
1
解决办法
5002
查看次数

dlopen - 未定义的符号错误

我正在使用dlopen在运行时加载共享库

dlopen("SharedLibarary1.so", RTLD_NOW | RTLD_GLOBAL);
Run Code Online (Sandbox Code Playgroud)

在该共享对象中,我引用另一个共享库"SharedLibarary2.so"中定义的const char*.

Executable和两个库都是使用-rdynamic构建的.

但是在使用dlopen时我仍然遇到运行时错误:"/ usr/lib/SharedLibarary1.so:undefined symbol"并指向错位的const char*有未定义的符号.

Whith GDB"info share"我可以看到第二个库没有在错误点加载.

如果我在第一个库之前在第二个库上执行dlopen,那问题怎么会消失.

有没有更好的方法来强制加载器为未解析的符号加载第二个库?

c c++ linux shared-libraries dlopen

7
推荐指数
1
解决办法
1万
查看次数

什么时候gcc __attribute __((构造函数))运行?

假设我有一个带有GCC构造函数的libA.so.

我的程序"程序"依赖于libA.so,所以当我运行它时,libA.so被打开并且它的构造函数被执行.现在,我还有一个模块libC.so,它也依赖于libA.我跑dlopen("libC.so"),加载libC,并根据我的实验,也执行libA的构造函数.

依赖关系看起来像这样:

  • libA有构造函数
  • libB也有一个构造函数
  • libC依赖于libA和libB
  • 程序取决于libA
  • 程序通过dlopen()链接libC

现在,当我运行程序时:

  • libA的构造函数在main()启动之前运行
  • libB的构造函数由dlopen()运行

显然,当它们被加载到内存中时,dlopen会执行库的构造函数.这是在某处指定的,链接器如何检查哪些库已经加载?

(为什么我要问:在一个场合,我在一些未完全理解的情况下得到了一个两次执行的构造函数.我是否正确地假设这完全被破坏并且在正常情况下不应该发生?)

c gcc posix shared-libraries dlopen

7
推荐指数
1
解决办法
1130
查看次数

在C中使用dlopen时,有没有一种优雅的方法来避免dlsym?

lib.so如果在运行时满足特定条件,则需要动态打开共享库。该库包含约700个函数,我需要加载所有符号。

一个简单的解决方案是定义指向其中包含的所有符号的函数指针lib.so,使用加载库dlopen,最后使用来获取所有符号的地址dlsym。但是,鉴于功能的数量,实现此解决方案的代码非常繁琐。

我想知道是否存在一个更优雅,更简洁的解决方案,也许是通过适当地使用宏来定义函数指针。谢谢!

c function-pointers shared-libraries dlopen

7
推荐指数
2
解决办法
3627
查看次数