ios7 - IOMobileFramebufferGetLayerDefaultSurface 不适用于 ios7 视网膜

标签 ios7 frameworks screen-capture retina

我想从后台服务捕获屏幕截图。在ios6和ios7下工作正常,但在ios7 retina下崩溃。

这是我的代码

{

IOMobileFramebufferConnection connect;
        kern_return_t result;
        m_screenSurfaceRef = NULL;

        io_service_t framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleH1CLCD"));
        if(!framebufferService)
            framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleM2CLCD"));
        if(!framebufferService)
            framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleCLCD"));

#pragma unused(result)
        result = IOMobileFramebufferOpen(framebufferService, mach_task_self(), 0, &connect);

        result = IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &m_screenSurfaceRef);

}

在视网膜上运行时,IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &m_screenSurfaceRef) 崩溃。

崩溃信息:

thread #1: tid = 0x1dfe9, 0x000000018ea2c270 IOMobileFramebufferIOMobileFramebufferGetLayerDefaultSurface + 4, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0x5e06dc28) frame #0: 0x000000018ea2c270 IOMobileFramebufferIOMobileFramebufferGetLayerDefaultSurface + 4

最佳答案

这是 IOMobileFramebuffer.h 逆向工程的 64 位问题。原型(prototype)为

IOMobileFramebufferReturn IOMobileFramebufferGetLayerDefaultSurface(IOMobileFramebufferConnection connection, int surface, CoreSurfaceBufferRef *ptr);

...不正确,因为 IOMobileFramebufferConnection 的 typedef 不正确。如果看一下 IOMobileFramebufferGetLayerDefaultSurface 的反汇编和部分反编译:

IOMobileFramebufferReturn IOMobileFramebufferGetLayerDefaultSurface(Connection *connection, int surface, IOSurfaceRef *ptr)
{
    if(connection) {                       // 0x18f95026c:  cbz    x0, 0x18f95027c
            long tmp = connection->unk2;   // 0x18f950270:  ldr    x3, [x0, #552] // <== Crash!
            if(tmp) {                      // 0x18f950274:  cbz    x3, 0x18f95027c
                    goto tmp;              // 0x18f950278:  br     x3
            }
   }
   //0x18f95027c:  movn   w0, #8191, lsl #16
   //0x18f950280:  movk   w0, #706
   //0x18f950284:  ret    lr

}

我们看到第一个参数被取消引用,这意味着它必须是指针大小的。在反向 header 中,IOMobileFramebufferConnection 被 typedef'd 为 io_connect_t,io_connect_t 被 typedef'd 为 io_object_t,即 mach_port_t,即 __darwin_mach_port_t,即 __darwin_natural_t,即 unsigned int! Int 在 32 位上恰好是指针大小,但不在 64 位以下,因此我们最终只是将指针的前 32 位发送到该函数中,这显然会崩溃。

我的解决方案是将 typedef 重新定义为 void*,如下所示:

typedef void *IOMobileFramebufferConnection;

完整的更正标题可以在 https://gist.github.com/nevyn/9486278 找到。 .

关于ios7 - IOMobileFramebufferGetLayerDefaultSurface 不适用于 ios7 视网膜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21870667/

相关文章:

java - 从 JPanel 创建小图像

ios - 重写drawRect : in UITableViewCell

xcode - iAd Banner 不出现但代码和权利

mysql - 使用 zend Framework 2 更新 mysql 记录

php - 一般 MVC 问题 - 命名、结构 (PHP)

java - 如何在java中获取当前的鼠标光标类型?

ios - Storyboard ui 元素不会出现在 Xcode 5 中

ios - 如何更改 UISearchBar 中 UITextField 的属性

rest - 关于 REST 全栈框架的建议?

ios - 如何禁止某些部分在 iOS 5 中显示为 TVOut?