如何从 C 方法调用 Objective-C 方法?
我有一个 Obj-C 对象,里面有很多方法。 有时一个方法需要调用同一对象内的另一个方法。 我似乎不知道如何让 C 方法调用 Obj-C 方法...
WORKS: Obj-C 方法调用 Obj-C 方法:
[self objCMethod];
WORKS:< /strong> Obj-C 方法调用 C 方法:
cMethod();
不起作用: C 方法调用 Obj-C 方法:
[self objCMethod]; // <--- this does not work
最后一个示例导致编译器吐出此错误:
错误:' self' 未声明(在此函数中首次使用)
两个问题。 为什么 C 函数看不到“self”变量,即使它位于“self”对象内部,以及如何调用它而不导致错误? 非常感谢您的帮助! :)
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...
WORKS: Obj-C method calling an Obj-C method:
[self objCMethod];
WORKS: Obj-C method calling a C method:
cMethod();
DOESN'T WORK: C method calling an Obj-C method:
[self objCMethod]; // <--- this does not work
The last example causes the compiler spits out this error:
error: 'self' undeclared (first use in this function)
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! :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
C 函数不是“
self
对象内部”。 事实上,什么也没有。Objective-C 方法有效地将 self 作为隐式参数,并在幕后完成了魔法。 对于普通 C 函数,它们不与任何类或对象关联,并且没有调用魔法,因此没有
self
。 如果需要它,则需要将其作为参数显式传递给 C 函数。C function is not "inside of the
self
object". In fact, nothing is.Objective-C methods effectively get
self
as 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 noself
. If you need it, you need to pass it to your C function explicitly as an argument.我知道 Aviad 已经回答了你的问题,但只是添加到信息中,因为这并非无关:
在我的例子中,我需要从我自己没有调用的 C 函数中调用 Objective-C 方法(触发了 Carbon Event 函数)通过注册全局热键事件),因此将 self 作为参数传递是不可能的。 在这种特殊情况下,您可以这样做:
在实现中定义一个类变量:
然后在 init 方法中将其设置为 self:
然后您可以从类中的任何 C 函数调用 Objective-C 方法,而无需传递
self
作为函数的参数:I know your question is already answered by Aviad but just to add to the info since this is not unrelated:
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:
Define a class variable in your implementation:
Then in your init method, set it to self:
You can then call Objective-C methods from any C function in the class without the need to pass
self
as a parameter to the function:为了使其工作,您应该像这样定义 C 方法:
当您调用它时,像这样调用它:
然后,您将能够编写:
在您的
cMethod
中。这是因为
self
变量是自动传递给 Objective-C 方法的特殊参数。 由于C方法不享有此特权,因此如果您想使用self
,则必须自己发送它。请参阅 编程指南的方法实现部分。
In order for that to work, you should define the C method like this:
and when you call it, call it like this:
then, you would be able to write:
In your
cMethod
.This is because the
self
variable is a special parameter passed to Objective-C methods automatically. Since C methods don't enjoy this privilege, if you want to useself
you have to send it yourself.See more in the Method Implementation section of the programming guide.
说实话,不存在 C 方法这样的东西。 C有函数。 为了说明差异,请看以下示例:
这是一个工作 C 程序,定义了一个类型和两个与之相关的函数:
这是该程序的 Objective-C 实现:
纯 C 程序的输出是:
Objective-C 程序的输出是:
唯一的区别是 NSLog 在文本之前放置的所有垃圾。 功能完全相同。 因此,在 C 中,您可以使用类似的方法,但它们实际上只是包含指向结构的指针的函数。
我认为这没有回答您最初的问题,但它确实解决了您似乎一直遇到的一些术语问题。
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:
This is a working C program that defines a type and two functions that go along with it:
Here is an Objective-C implementation of that program:
The output of the pure C program was:
The output of the Objective-C program was:
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.
I don't think this answered your original question, but it did clear up some terminology issues you appear to have been having.
据我所知,有两种选择。 您应该根据您的需要选择一个。
简单
第一个是通过 C ABI 兼容函数封装和公开 ObjC API。 这样,您将能够从 C 代码调用该函数并保留大部分类型安全性。 您可以将 ObjC 类的引用作为参数 struct objc_class *foo 传递,但我尚未对此进行测试。
灵活
另一种选择是使用 ObjC 运行时。 这样,您就不需要直接编译 Objective C 作为程序的一部分。 这种方法的缺点是完全失去类型安全性。 此外,您需要做出编译器通常为您做的决定。 例如,您需要使用 objc_msgSend 或 objc_msgSend_stret ,具体取决于 上下文。 不要忘记包含
-framework Cocoa
或您需要的任何内容作为编译器标志的一部分。据我所知,它对于语言绑定来说非常好,因为您只需要关心编译 C 代码并传递类型就变得非常容易。
There are two options from what I can tell. You should pick one depending on your needs.
Easy
The first one is encapsulating and exposing the ObjC API via C ABI compatible functions. This way, you will be able to call the function from C code and retain most type safety. Potentially, you could pass a reference to the ObjC class as argument
struct objc_class *foo
, but I have not tested this.Flexible
The other option is to use the ObjC runtime. This way, you won't need to directly compile Objective C as part of your program. This approach comes with the drawback of completely loosing type safety. Furthermore, you will need to make decisions the compiler normally does for you. As an example, you will need to use
objc_msgSend
orobjc_msgSend_stret
depending on the context. Do not forget to include-framework Cocoa
or whatever you need as part of your compiler flags.As far as I can tell, it is really nice for language bindings, because you only have to care about compiling C code and passing types around becomes super easy.
到目前为止给出的答案的另一个选择是使用
objc_msgSend()
由 Objective-C 运行时提供的函数。Another option to the answers given thus far is to use the
objc_msgSend()
function provided by the Objective-C runtime.