有没有办法来包装一个ObjectiveC块插入函数指针? [英] Is there a way to wrap an ObjectiveC block into function pointer?

查看:192
本文介绍了有没有办法来包装一个ObjectiveC块插入函数指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要为某一特定的C库C风格的回调在iOS应用。回调没有 void *的用户数据或类似的东西。所以我不能够在上下文中循环。我想避免引入全球范围内解决这个问题。一个理想的解决方案将是一个Objective-C块。

I have to provide a C-style callback for a specific C library in an iOS app. The callback has no void *userData or something similar. So I am not able to loop in a context. I'd like to avoid introducing a global context to solve this. An ideal solution would be an Objective-C block.

我的问题:是否有'投'块到一个函数指针或换行/不知何故披风吧办法

My question: Is there a way to 'cast' a block into a function pointer or to wrap/cloak it somehow?

推荐答案

从技术上讲,你可以得到访问该块的函数指针。但是,这是完全不安全的话,那么我当然不建议这样做。要了解如何,请看下面的例子:

Technically, you could get access to a function pointer for the block. But it's totally unsafe to do so, so I certainly don't recommend it. To see how, consider the following example:

#import <Foundation/Foundation.h>

struct Block_layout {
    void *isa;
    int flags;
    int reserved; 
    void (*invoke)(void *, ...);
    struct Block_descriptor *descriptor;
};

int main(int argc, char *argv[]) {
    @autoreleasepool {
        // Block that doesn't take or return anything
        void(^block)() = ^{
            NSLog(@"Howdy %i", argc);
        };

        // Cast to a struct with the same memory layout
        struct Block_layout *blockStr = (struct Block_layout *)(__bridge void *)block;

        // Now do same as `block()':
        blockStr->invoke(blockStr);




        // Block that takes an int and returns an int
        int(^returnBlock)(int) = ^int(int a){
            return a;
        };

        // Cast to a struct with the same memory layout
        struct Block_layout *blockStr2 = (struct Block_layout *)(__bridge void *)returnBlock;

        // Now do same as `returnBlock(argc)':
        int ret = ((int(*)(void*, int a, ...))(blockStr2->invoke))(blockStr2, argc);
        NSLog(@"ret = %i", ret);
    }
}

运行该收益率:

Howdy 1
ret = 1

这就是我们希望从单纯的执行这些块直接与块期望()。所以,你可以使用调用作为你的函数指针。

Which is what we'd expect from purely executing those blocks directly with block(). So, you could use invoke as your function pointer.

但正如我所说,这完全是不安全的。实际上并不使用这个!

如果你想看到的方式做你问什么是写了,然后检查了这一点:
http://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-$c$c.html

If you want to see a write-up of a way to do what you're asking, then check this out: http://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-code.html

这是你需要做的就是这个工作什么只是一个伟大的写了。可悲的是,它永远不会在iOS的工作,虽然(因为你需要标记的网页作为你不允许你的应用程序的沙箱中做的可执行文件)。但无论如何,一个伟大的文章。

It's just a great write-up of what you would need to do to get this to work. Sadly, it's never going to work on iOS though (since you need to mark a page as executable which you're not allowed to do within your app's sandbox). But nevertheless, a great article.

这篇关于有没有办法来包装一个ObjectiveC块插入函数指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆