有没有办法使用它的路径找到 dylib 的版本?我正在寻找可以接受与 dlopen 相同参数的东西。我查看了 NSVersionOfRunTimeLibrary,但从我阅读文档看来,它获取的是当前 dylib 的版本,而不是路径中指定的版本。
谢谢
运行otool -L
它,它会显示它的实际版本。我选择 libSystem.B 因为它在 10.4 和 10.5 SDK 中有不同的版本:
$ otool -L /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib
/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11)
/usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 220.0.0)
$ otool -L /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib
/Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4)
/usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 292.4.0)
(看看第一个有 88.3.11 版本,而第二个有 111.1.4)。此示例还表明,并非所有库都是指向带有版本号的文件的符号链接:
$ ll /Developer/SDKs/MacOSX10.*.sdk/usr/lib/libSystem.B.dylib
-rwxr-xr-x 1 root wheel 749K May 15 2009 /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib
-rwxr-xr-x 1 root wheel 670K May 15 2009 /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib
-rwxr-xr-x 1 root wheel 901K Sep 25 00:21 /Developer/SDKs/MacOSX10.6.sdk/usr/lib/libSystem.B.dylib
在这里,文件的名称中没有版本号。
编辑:第二种解决方案是NSVersionOfRunTimeLibrary
在测试程序中使用,在该程序中强制加载要检查的库。libversion
从以下 C 源代码创建一个程序:
#include <stdio.h>
#include <mach-o/dyld.h>
int main (int argc, char **argv)
{
printf ("%x\n", NSVersionOfRunTimeLibrary (argv[1]));
return 0;
}
然后,你这样称呼它:
$ DYLD_INSERT_LIBRARIES=/usr/lib/libpam.2.dylib ./a.out libpam.2.dylib
30000
(这里,版本号打印为十六进制,但您可以根据自己的需要进行调整。)
您可以在此处查看 NSVersionOfRunTimeLibrary 的源代码: http ://www.opensource.apple.com/source/dyld/dyld-132.13/src/dyldAPIsInLibSystem.cpp
基于此,您可以创建自己的版本替换if(names_match(install_name, libraryName) == TRUE)
为if(strcmp(_dyld_get_image_name(i), libraryName) == 0)
That 将解决原始预期库名称没有完整路径的问题,编辑后的版本需要完整路径,但它仍会在加载的 dylibs 中搜索。
#include <mach-o/dyld.h>
int32_t
library_version(const char* libraryName)
{
unsigned long i, j, n;
struct load_command *load_commands, *lc;
struct dylib_command *dl;
const struct mach_header *mh;
n = _dyld_image_count();
for(i = 0; i < n; i++){
mh = _dyld_get_image_header(i);
if(mh->filetype != MH_DYLIB)
continue;
load_commands = (struct load_command *)
#if __LP64__
((char *)mh + sizeof(struct mach_header_64));
#else
((char *)mh + sizeof(struct mach_header));
#endif
lc = load_commands;
for(j = 0; j < mh->ncmds; j++){
if(lc->cmd == LC_ID_DYLIB){
dl = (struct dylib_command *)lc;
if(strcmp(_dyld_get_image_name(i), libraryName) == 0)
return(dl->dylib.current_version);
}
lc = (struct load_command *)((char *)lc + lc->cmdsize);
}
}
return(-1);
}