我在 OSX 上有一个库 libni,我正在尝试使用 dlopen() 打开,它似乎无法将依赖关系解析为另一个 dlopen()'d 库。
让我们不要讨论为什么不应该使用 dlopen(); 可以说,我必须在这种情况下使用它。
无论如何,这是 libni.dylib 上的 otool -L:
lib/libni.dylib:
libni.dylib (compatibility version 0.0.0, current version 0.0.0)
libn.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
libzlib.dylib (compatibility version 0.0.0, current version 0.0.0)
libpng.dylib (compatibility version 0.0.0, current version 0.0.0)
liblua.dylib (compatibility version 0.0.0, current version 0.0.0)
libSDL2.0.dylib (compatibility version 0.0.0, current version 2.0.0)
libstb.dylib (compatibility version 0.0.0, current version 0.0.0)
libax.dylib (compatibility version 0.0.0, current version 0.0.0)
libsqlite3.dylib (compatibility version 0.0.0, current version 0.0.0)
libfreetype.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 19.0.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/System/Library/Frameworks/ForceFeedback.framework/Versions/A/ForceFeedback (compatibility version 1.0.0, current version 1.0.2)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 155.0.0)
/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit (compatibility version 1.0.0, current version 1.0.0)
这是在 libn、zlib 和 png 上:
libn.dylib:
libn.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
libpng.dylib:
libpng.dylib (compatibility version 0.0.0, current version 0.0.0)
libzlib.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
libzlib.dylib:
libzlib.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
现在我使用 dlopen() 按顺序打开我的“lib”目录中的所有动态库,使用:
/** Open a dynamic library file */
void *Type__(open) (char *path) {
void *impl = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if (impl == NULL) {
char *err = dlerror();
N_LOG(N_LOG_DEBUG, "Failed to open: %s", err);
}
else {
N_LOG(N_LOG_DEBUG, "Happy open: %s", path);
rtn = nPosixLinker__Lib(path, impl);
}
return rtn;
}
...并得到这样的错误/消息:
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libzlib.dylib
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libstb.dylib
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libsqlite3.dylib
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libSDL2.dylib
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libn.dylib
Failed to open: dlopen(/Users/doug/projects/libni/build/tests/IImageLoader/lib/libpng.dylib, 10): Library not loaded: libzlib.dylib
Referenced from: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libpng.dylib
Reason: image not found
Failed to open: dlopen(/Users/doug/projects/libni/build/tests/IImageLoader/lib/libni.dylib, 10): Library not loaded: libn.dylib
Referenced from: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libni.dylib
Reason: image not found
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/liblua.dylib
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libfreetype.dylib
Happy open: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libax.dylib
Failed to open: dlopen(/Users/doug/projects/libni/build/tests/IImageLoader/lib/libtest-ni-IImageLoader__.dylib, 10): Library not loaded: libni.dylib
Referenced from: /Users/doug/projects/libni/build/tests/IImageLoader/lib/libtest-ni-IImageLoader__.dylib
Reason: image not found
所以这里肯定发生了一些奇怪的事情。zlib 在 libpng 之前打开,但 libpng 无法解析引用。libn 在 libni 之前打开,但 libni 无法解析引用。
就像我的 RTLD_GLOBAL 被 dlopen() 忽略了,或者依赖项(例如 libn)没有找到加载的库(blah/libn.dylib),因为路径不同......
事实上,我似乎无法让 dlopen() 打开一个完全有依赖关系的库,所以我认为我一定做错了什么。
有什么建议么?
在 BSD 和 linux 上,这一切都行得通;这绝对是一个与 OSX 处理这些库的方式严格相关的问题。