在客观-C“转换”的函数指针到一个块(“Converting” a function pointer

2019-08-04 05:04发布

我是从单声道C#中的OBJ-C做了一些互操作性,并就遇到了这个问题。 C#代码需要通过一个回调 - 它与一个函数指针一样。 我可以从对象 - 侧获取函数指针,并调用它,一切正常。 但是我现在需要给这个函数指针作为回调第三方API与块作为回调的作品。 我想第三方调用C#功能 - 这样的方法,我想无论是函数指针转换为块,以便第三方可以运行它,或作出某种形式的桥梁 - 创建自己的块运行该函数指针,并把它交给第三方。 我似乎无法找到一个方法来做到这一点 - 我将如何生成信息,其中函数运行,然后把它交给第三方块。 也许有我的另一种选择?

编辑:把功能在一个全局变量可能的工作,但我希望能有这些作为第三方API的许多是异步的,我不希望它调用了错误的回调。

代码我尝试:

typedef void (*DummyAction)(char * result);
typedef void (^DummyBlock)(char * result);

@interface FunctionToBlock : NSObject
{
    DummyAction function;
    DummyBlock block;
}

- (id) initWithFunction: (DummyAction) func;
- (DummyBlock) block;
@end

@implementation FunctionToBlock : NSObject
- (id) initWithFunction: (DummyAction) func {
    if (self = [super init]) {
        function = func;
        block = ^(char * result) {
            function(result);
        };
    }
    return self;
}

- (DummyBlock) block {
    return block;
}
@end

然后,我用这个运行

void RegisterCallback( char * text, DummyAction callback)
{
    FunctionToBlock *funcToBlock = [[FunctionToBlock alloc] initWithFunction : callback];
    funcToBlock.block(text);
}

而它失败BAD_ACCESS。 也许是我做错了什么,因为我不是很精通的OBJ-C呢。 我可以证实,如果直接运行,该块被称为回调是好的,但它的功能(结果)线失败。

Answer 1:

为什么不只是有一个简单的函数

typedef void (*DummyAction)(char * result);
typedef void (^DummyBlock)(char * result);

DummyBlock functionToBlock(DummyAction func) {
    return [[^(char * result) {
                 func(result);
             } copy] autorelease];
}


Answer 2:

关于什么

void (*myFunc)(int x); // ... your function pointer

void (^myBlock)(int) = ^(int x) {
    myFunc(x);
};

然后myBlock是捕获的函数指针的值,并执行该块时调用该函数的块。


补充:建议,根据你的代码,使用@property(并假设你有ARC编译):

FunctionToBlock.h:

typedef void (*DummyAction)(char * result);
typedef void (^DummyBlock)(char * result);

@interface FunctionToBlock : NSObject
{
    DummyAction function; // Not really needed.
}

- (id) initWithFunction: (DummyAction) func;
@property(copy, nonatomic) DummyBlock block;   // "copy" is important here!

@end

FunctionToBlock.m:

#import "FunctionToBlock.h"

@implementation FunctionToBlock : NSObject
@synthesize block = _block; // Can be ommitted if you use Xcode 4.4 or later.

- (id) initWithFunction: (DummyAction) func
{
    if (self = [super init]) {
        function = func; // Not really needed.
        self.block = ^(char * result) {
            func(result); // Use "func", not "self->function", to avoid retain cycle.
        };
    }
    return self;
}


Answer 3:

A嵌段是引擎盖下一个指针到一个本地数据结构。 块只要你离开它被宣布范围变为无效。 该范围内的init if语句; 只要你离开的是,该块是无效的。

您在这里打破编码约定在一个糟糕的方式。 首先,实例变量应以下划线开始,让大家看到你在做什么。 最好使用性能,而完全不声明实例变量。 而每块属性应该被宣布为“复制”。 如果你这样做,一切都很好。



文章来源: “Converting” a function pointer to a block in objective-C