我的代码在越狱 iOS 中使用 dlsym 动态获取常量有什么问题?

What's wrong with my code to dynamically get constants with dlsym in jailbroken iOS?

我需要在我的代码中使用 kIOSurfaceWidth 来捕获屏幕截图,但是苹果已经从 iOS 9.3 中删除了 PrivateFrameworks,所以我必须加载 IOSurface.frameworks 在运行时动态。我使用下面的代码,但 return 在 dlsym 之后不为空,但是当我尝试 NSLog kIOSurfaceWidth 的值时,它崩溃了。谁能帮帮我?

static CFStringRef _kIOSurfaceWidth;

static void load()
{
    void* handle = dlopen("/System/Library/PrivateFrameworks/IOSurface.framework/IOSurface", RTLD_LAZY);

    _kIOSurfaceWidth = dlsym(RTLD_DEFAULT, "kIOSurfaceWidth");
    if (!_kIOSurfaceWidth) LOG_GENERAL(@">>>>>>>> _kIOSurfaceWidth is NULL");
    else NSLOG(@"_kIOSurfaceWidth is %@", (NSString *)CFBridgingRelease(_kIOSurfaceWidth));
}

dlsym() 给你符号的地址,而不是它的值。像这样更改您的代码:

static CFStringRef *_kIOSurfaceWidth;

static void load()
{
    void* handle = dlopen("/System/Library/PrivateFrameworks/IOSurface.framework/IOSurface", RTLD_LAZY);

    _kIOSurfaceWidth = dlsym(RTLD_DEFAULT, "kIOSurfaceWidth");
    if (!_kIOSurfaceWidth) LOG_GENERAL(@">>>>>>>> _kIOSurfaceWidth is NULL");
    else NSLog(@"*_kIOSurfaceWidth is %@", *_kIOSurfaceWidth);
}

您还有其他问题。您的日志行使用的 kIOSurfaceWidth 没有前导下划线 (_),因此它不是指您的变量。

您正在调用 CFBridgingRelease(),除非您有所有权参考,否则这是不合适的。它仅适用于您有权使用 CFRelease() 的情况,这就是它的命名方式相似的原因。不需要进行转换、桥接或其他操作,只需将字符串引用作为参数传递给 NSLog().