dlopen 与标准动态链接的用例是什么?

What are the use cases of dlopen vs standard dynamic linking?

根据文档,dlopendlsym 结合使用以加载库,并获取指向符号的指针。

但这已经是动态 loader/linker 所做的。 而且,这两种方法都是基于ld.so

使用dlopen时实际上似乎有两个区别:

  1. 可以有条件地加载库。
  2. 编译器不知道我们正在使用的符号(类型、原型...),因此不会检查潜在的错误。顺便说一下,这是一种实现内省的方法。

但是,它似乎并没有激发 dlopen 在标准加载上的使用,边缘示例除外:

  1. 就内存占用优化而言,当共享库已被另一个程序使用时,条件加载并不是很有趣:加载已使用的库不会增加内存占用。
  2. 避免编译器监督是不安全的,也是编写错误的好方法...我们还缺少潜在的编译器优化。

那么,是否还有其他用途 dlopen 优于标准动态 linking/loading?

我在 Windows 环境中这样做是为了构建语言切换功能。当我的应用程序启动时,它会检查应该使用 language.dll 的配置设置。从现在开始,所有文本都从动态加载的库中加载,甚至可以在运行时替换。我还包含了一个用于格式化序数(第一、第二、第三)的函数,它是特定于语言的。我在可执行文件中包含了我的母语的语言资源,所以我不能最终没有可用的文本。

关键是可执行文件可以在运行时决定应该加载哪个库。在我的例子中,这是一个语言切换,或者正如评论员所说的那样,就像插件的目录扫描。

缺乏对调用签名的监控绝对是一个缺点。如果你真的想做坏事,比如覆盖原型类型定义,你可以用标准的 C 类型转换来做到这一点。

So, are there other uses where dlopen is prefered over the standard dynamic linking/loading?

使用 dlopen 的典型用例是

  • 插件
  • select当前 CPU 的最佳实现(英特尔数学库执行此操作)
  • select API 由不同供应商实施(GLEW 和其他 OpenGL 包装器执行此操作)
  • 延迟加载共享库,如果它不太可能被使用(这会加快启动速度,因为库构造函数不会 运行 + 运行时间链接器要做的工作会稍微少一些)

Avoiding the compiler supervision is unsafe and a good way to write bugs... We're also missing the potential compiler optimizations.

的确如此,但您可以通过围绕延迟加载的共享库提供一个小型包装库来两全其美。在 Windows 上,这是通过标准工具完成的(google for "DLL import libraries"),在 Linux 上,您可以手动完成或使用 Implib.so.