首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >objc_msgSend和联合

objc_msgSend和联合
EN

Stack Overflow用户
提问于 2013-07-16 03:12:46
回答 1查看 769关注 0票数 4

当我有返回一些联合的方法时,我有一个与objc_msgSend运行时调用相关的问题。

我通过libffi调用objc_msgSend函数,如果union小于16B,一切都很好,但是如果union的大小大于16B,我会得到seg错误。我尝试使用objc_msgSend_stret函数,它通过了,但是我得到了返回的联合的错误值,并且我不确定用哪个函数来调用联合。

有没有人知道objective c中的联合,在objc运行时是如何处理的?

EN

回答 1

Stack Overflow用户

发布于 2013-07-16 03:20:12

当您使用objc_msgSend时,这是一个HUUUUGE问题;基本上,大多数ABI喜欢将它们的返回值放在寄存器中(对于勇敢和好奇的http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/000-Introduction/introduction.html来说,这里是所有血淋淋的细节),但有些对象就是无法放入寄存器(这就是为什么联合大小<= 16适合您)。相反,您需要使用您希望您的工会加入的地址来调用objc_msgSend_stret

另一个很好的参考:http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/c/func/objc_msgSend_stret

解决方案:转换并调用objc_msgSend_stret,而不是强制转换和调用objc_msgSend

代码语言:javascript
复制
void objc_msgSend_stret(void * stretAddr, id theReceiver, SEL theSelector,  ...)

所以你的造型应该是(像using objc_msgSend to call a Objective C function with named arguments一样):

代码语言:javascript
复制
union myUnion {
    int a, b;
    char c;
    double d;
};

// For objc_msgSend_stret
void (*objc_msgSend_stretTyped)(union myUnion* stretAddr, id self, SEL _cmd, float bar) = (void*)objc_msgSend_stret;

union myUnion u;
float pi = 4;

objc_msgSend_stretTyped(&u, obj, sel_getUID(sel), pi);

编辑--跳过上面的所有代码

下面是我如何让objc_msgSend_stret正常工作的:

代码语言:javascript
复制
#import "ViewController.h"
#import <objc/runtime.h>
#import <objc/objc.h>

@interface ViewController ()

@end

union myUnion {
    int myArray[32];
    int a,b,c,d;
};

void doStuff(id obj, SEL sel);

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    doStuff(self, @selector(doStuff:));
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (union myUnion) doStuff: (int)myInt {
    NSLog(@"Pi equals %d", myInt);
    union myUnion u;
    for(int i=0; i<32; i++) {
        u.myArray[i] = i*i*i*i-1;
    }
    return u;
}

@end

void doStuff(id obj, SEL sel) {
    int pi = 4;
    NSLog(@"myUnion is: %luB", sizeof(union myUnion));
    NSLog(@"Sizeof(int) = %luB ... Sizeof(char) = %lub ... sizeof(double) = %luB", sizeof(int), sizeof(char), sizeof(double));

    union myUnion u = ((union myUnion(*)(id, SEL, int))objc_msgSend_stret)(obj, sel, pi);
    NSLog(@"Union u = {%d, %d, %d, %d}", u.myArray[30], u.myArray[29], u.myArray[28], u.myArray[27]);
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17662011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档