如何从 C 方法调用 Objective-C 方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1280017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:04:44  来源:igfitidea点击:

How to call an Objective-C Method from a C Method?

objective-cself

提问by Dave Gallagher

I have an Obj-C object with a bunch of methods inside of it. Sometimes a method needs to call another method inside the same object. I can't seem to figure out how to get a C method to call a Obj-C method...

我有一个 Obj-C 对象,里面有一堆方法。有时一个方法需要调用同一个对象内的另一个方法。我似乎无法弄清楚如何让 C 方法调用 Obj-C 方法......

WORKS:Obj-C method calling an Obj-C method:

WORKS:Obj-C 方法调用 Obj-C 方法:

[self objCMethod];

WORKS:Obj-C method calling a C method:

WORKS:Obj-C 方法调用 C 方法:

cMethod();

DOESN'T WORK:C method calling an Obj-C method:

不起作用:C 方法调用 Obj-C 方法:

[self objCMethod];     // <--- this does not work

The last example causes the compiler spits out this error:

最后一个例子导致编译器吐出这个错误:

error: 'self' undeclared (first use in this function)

错误:'self' 未声明(首次在此函数中使用)

Two questions. Why can't the C function see the "self" variable even though it's inside of the "self" object, and how do I call it without causing the error? Much thanks for any help! :)

两个问题。为什么 C 函数看不到“self”变量,即使它在“self”对象内部,我如何调用它而不导致错误?非常感谢您的帮助!:)

回答by Aviad Ben Dov

In order for that to work, you should define the C method like this:

为了使其工作,您应该像这样定义 C 方法:

void cMethod(id param);

and when you call it, call it like this:

当你调用它时,像这样调用它:

cMethod(self);

then, you would be able to write:

然后,您将能够编写:

[param objcMethod];

In your cMethod.

在您的cMethod.

This is because the selfvariable is a special parameter passed to Objective-C methods automatically. Since C methods don't enjoy this privilege, if you want to use selfyou have to send it yourself.

这是因为self变量是自动传递给 Objective-C 方法的特殊参数。由于C方法不享有这个特权,如果你想使用self你必须自己发送它。

See more in the Method Implementation section of the programming guide.

请参阅编程指南方法实现部分中的更多信息。

回答by Form

I know your question is already answered by Aviad but just to add to the info since this is not unrelated:

我知道 Aviad 已经回答了您的问题,但只是为了添加信息,因为这并非无关:

In my case I needed to call an Objective-C method from a C function that I did not call myself (a Carbon Event function triggered by registering a global hotkey event) so passing self as a parameter was impossible. In this particular case you can do this:

在我的例子中,我需要从一个我没有调用自己的 C 函数调用一个 Objective-C 方法(一个由注册全局热键事件触发的碳事件函数),因此将 self 作为参数传递是不可能的。在这种特殊情况下,您可以这样做:

Define a class variable in your implementation:

在您的实现中定义一个类变量:

id thisClass;

Then in your init method, set it to self:

然后在您的 init 方法中,将其设置为 self:

thisClass = self;

You can then call Objective-C methods from any C function in the class without the need to pass selfas a parameter to the function:

然后,您可以从类中的任何 C 函数调用 Objective-C 方法,而无需将其self作为参数传递给函数:

void cMethod([some parameters]) {
    [thisClass thisIsAnObjCMethod];
}

回答by Pavel Minaev

C function is not "inside of the selfobject". In fact, nothing is.

C 函数不是“self对象内部”。事实上,什么都不是。

Objective-C methods effectively get selfas an implicit argument, with magic done under the hood. For plain C functions, they aren't associated with any class or object, and there's no call magic, so no self. If you need it, you need to pass it to your C function explicitly as an argument.

Objective-C 方法有效地self作为一个隐式参数,在幕后完成了魔术。对于普通的 C 函数,它们不与任何类或对象相关联,并且没有调用魔法,所以没有self. 如果您需要它,您需要将它作为参数显式传递给您的 C 函数。

回答by Jonathan Sterling

To be totally truthful, there is no such thing as a C method. C has functions. To illustrate the difference, look at the following examples:

老实说,没有 C 方法这样的东西。C 有函数。为了说明差异,请看以下示例:

This is a working C program that defines a type and two functions that go along with it:

这是一个工作 C 程序,它定义了一个类型和两个与之相关的函数:

#include <stdio.h>

typedef struct foo_t {
    int age;
    char *name;
} Foo;

void multiply_age_by_factor(int factor, Foo *f) {
    f->age = f->age * factor;
}

void print_foo_description(Foo f) {
    printf("age: %i, name: %s\n", f.age, f.name);
}

int main() {
    Foo jon;
    jon.age = 17;
    jon.name = "Jon Sterling";

    print_foo_description(jon);
    multiply_age_by_factor(2, &jon);
    print_foo_description(jon);

    return 0;
}

Here is an Objective-C implementation of that program:

这是该程序的 Objective-C 实现:

#import <Foundation/Foundation.h>

@interface Foo : NSObject {
    NSUInteger age;
    NSString *name;
}

@property (nonatomic, readwrite) NSUInteger age;
@property (nonatomic, copy) NSString *name;

- (void)multiplyAgeByFactor:(NSUInteger)factor;
- (NSString *)description;
- (void)logDescription;

@end


@implementation Foo 
@synthesize age;
@synthesize name;

- (void)multiplyAgeByFactor:(NSUInteger)factor {
    [self setAge:([self age] * factor)];
}

- (NSString *)description {
    return [NSString stringWithFormat:@"age: %i, name: %@\n", [self age], [self name]];
}

- (void)logDescription {
    NSLog(@"%@",[self description]);
}

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Foo *jon = [[[Foo alloc] init] autorelease];
    [jon setAge:17];
    [jon setName:@"Jon Sterling"];

    [jon logDescription];
    [jon multiplyAgeByFactor:2];
    [jon logDescription];

    [pool drain];

    return 0;
}

The output of the pure C program was:

纯C程序的输出是:

age: 17, name: Jon Sterling
age: 34, name: Jon Sterling

The output of the Objective-C program was:

Objective-C 程序的输出是:

2009-08-25 17:40:52.818 test[8963:613] age: 17, name: Jon Sterling
2009-08-25 17:40:52.828 test[8963:613] age: 34, name: Jon Sterling

The only difference is all the junk that NSLog puts before the text. The functionality is exactly the same. So, in C, you can use something sort of like methods, but they are really just functions that include a pointer to a struct.

唯一的区别是 NSLog 放在文本之前的所有垃圾。功能完全一样。因此,在 C 中,您可以使用某种类似的方法,但它们实际上只是包含指向结构的指针的函数。

I don't think this answered your original question, but it did clear up some terminology issues you appear to have been having.

我不认为这回答了您最初的问题,但它确实解决了您似乎遇到的一些术语问题。

回答by Dave DeLong

Another option to the answers given thus far is to use the objc_msgSend()function provided by the Objective-C runtime.

到目前为止给出的答案的另一个选择是使用objc_msgSend()Objective-C 运行时提供的函数。