当两个 macOS .plugin 依赖于相同的 .dylib 并且每个都将其单独捆绑在插件的文件夹中时会发生什么?

What happens when two macOS .plugin depend on same .dylib and each bundles it separately inside plugins' folder?

我有两个插件 pluginA.pluginpluginB.plugin,它们都依赖于同一个库 libC.dylib。构建插件时,我递归地检查动态依赖项(使用 otool -L),复制每个插件的 libs 文件夹中的所有依赖项,并使用 install_name_tool 调整依赖项路径,即 "carrying all all my stuff with me" 方法.

我想了解当这两个插件将被某些程序加载时发生了什么? libC.dylib 会被加载两次,这会导致运行时崩溃吗?或者运行时会意识到同一个 dylib 有两个副本(基于版本?)而只使用一个?

Apple的Dynamic Library Usage Guidelines

中描述了动态库搜索和加载的顺序

简而言之,如果您的插件中依赖库的路径匹配,则该库将只加载一次。在每次下一次加载时,只会增加内部计数器:

The dlopen function returns the same library handle it returned in the first call, but it also increments the reference count associated with the handle

如果库的路径不同,将加载库的不同副本。

注意:在检查库是否已经加载时,使用的是它的绝对路径。它可以直接在依赖中设置,在全局目录中搜索时发现,或者从@rpath 中解析。

关于符号解析过程中的潜在冲突:

Name conflicts between dynamic shared libraries are not discovered at compile time, link time, or runtime. The dlsym function uses string matching to find symbols. If two libraries use the same name for a function, the dynamic loader returns the first one that matches the symbol name given to dlsym.

因此,如果两个插件使用相同的库,则多个副本不会导致程序崩溃。如果他们希望使用同名的不同库,那将是一个大问题,您应该使用版本兼容机制 - 请参阅 Dynamic Library Design Guidelines