OSX:无法使用dlopen()解析依赖项

时间:2022-09-04 11:12:39

I have a library libni on OSX I'm trying to open using dlopen(), and it can't seem to resolve the dependencies to another dlopen()'d library.

我在OSX上有一个库libni我试图使用dlopen()打开它,它似乎无法将依赖关系解析为另一个dlopen()'d库。

Lets not get into why you shouldn't use dlopen(); suffice to say, I have to use it in this circumstance.

让我们不要理解为什么你不应该使用dlopen();足以说,我必须在这种情况下使用它。

Anyway, so this is otool -L on libni.dylib:

无论如何,这是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)

and this is on libn, zlib and png:

这是在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)

Now I use dlopen() to open all the dynamic libraries in my 'lib' dir, in order, using:

现在我使用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;
}

...and get errors/messages like this:

...并获取如下错误/消息:

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

So there's definitely something weird going on here. zlib is opened before libpng, but libpng can't resolve the reference. libn is opened before libni, but libni can't resolve the reference.

所以这里肯定会发生一些奇怪的事情。在libpng之前打开zlib,但是libpng无法解析引用。 libn在libni之前打开,但libni无法解析引用。

It's like my RTLD_GLOBAL is being ignored by dlopen(), or the dependency (eg. libn) isn't finding the loaded library (blah/libn.dylib) because the paths are different...

这就像我的RTLD_GLOBAL被dlopen()忽略,或者依赖(例如.libn)没有找到加载的库(blah / libn.dylib),因为路径不同......

In fact, I cant seem to make dlopen() open a library which has a dependency at all so I figure I must be doing something wrong.

事实上,我似乎无法让dlopen()打开一个完全依赖的库,所以我想我一定做错了。

Any suggestions?

On BSD and linux this all just works; it's definitely an issue strictly related to the way OSX is handling these libraries.

在BSD和Linux上,这一切都正常;这绝对是一个与OSX处理这些库的方式有关的问题。

1 个解决方案

#1


0  

Looks like this is a duplicate of this, but I totally didn't find it until after I already figured out the solution, so I'm going to leave both the question and this link here for now.

看起来这是一个副本,但我完全没有找到它,直到我已经找到解决方案,所以我现在将留下问题和这个链接。

Sort answer: Build the library using -install_name @rpath/lib

排序答案:使用-install_name @ rpath / lib构建库

#1


0  

Looks like this is a duplicate of this, but I totally didn't find it until after I already figured out the solution, so I'm going to leave both the question and this link here for now.

看起来这是一个副本,但我完全没有找到它,直到我已经找到解决方案,所以我现在将留下问题和这个链接。

Sort answer: Build the library using -install_name @rpath/lib

排序答案:使用-install_name @ rpath / lib构建库