如何在MacRuby中使用C / Obj-C可变参数函数?

时间:2012-03-20 23:45:15

标签: macruby variadic-templates

我在Obj-C类中声明了一个可变函数/方法,如下所示:

@interface Foo
+ (void) print: (id) firstMessage, ...;
@end

@implementation
+ (void) print: (id) firstMessage, ...{
    va_list ap
    va_start (ap, firstMessage)
    for (id message = firstMessage; message != nil; message = va_arg(ap, id)){
        NSLog(@"message: %@", message);
    }
    va_end(ap)
}
@end

这适用于Obj-C函数调用,如下所示:

[Foo print: @"Hello, world.", @"I'm Xavier.", nil];

控制台会打印:

=> Hello, world.
=> I'm Xavier.

但是当我在MacRuby中调用函数调用时它不起作用:

Foo.print (@"Hello, world.", @"I'm Xavier.", nil)

控制台然后打印:

=> Hello, world.
=> Hello, world.
=> (lldb)

是的,它打印第一条消息两次!然后就崩溃了。

我发现作业" message = va_arg(ap,id)"不起作用。 消息 obj不会发生变化。我认为这可能是MacRuby(版本0.10)中的一个问题。

我认为MacRuby只接受第一个参数并将其传递给Obj-C方法。不是吗?我错了吗?

1 个答案:

答案 0 :(得分:1)

您需要为Objective-C类生成桥接支持文件。

如何?

您可以通过阅读gen_bridge_metadata的手册页找到有关如何执行此操作的完整详细信息。如果您的Obj-C类是框架的一部分,则在MacRuby中使用framework方法还将包含正确的桥支持文件。如果您直接链接,则可能需要使用Kernel.load_bridge_support_file

为什么?

MacRuby无法从运行时元数据推断出方法是否为可变参数。这与可变方法具有与非可变方法不同的调用约定这一事实相结合,意味着MacRuby在调用可变参数方法时总是会崩溃,除非事先以某种方式告知它需要使用可变参数调用约定。这就是Bridge Support提供的功能。