从MAC OS X中的c++dylib调用cocoa/obj-c方法

Call a cocoa/obj-c method from a C++ dylib in MAC OS X

本文关键字:cocoa obj-c 方法 调用 c++dylib MAC OS 中的      更新时间:2023-10-16

由于我对Objective-C编程语言还很陌生,我面临着一个巨大的问题:如何通过向它传递一些参数,从我的动态加载库(用C++制作)中调用我的应用程序(用Objective-C制作)的方法?

我已经在网上挖了几天了,运气不好。我唯一发现的是IMP,但我不确定这是否是我需要的。

实际上这里有很多选项。

  1. 如果dylib是你自己的,你可以通过Objective-C调用将其编译为Mac OS X和#ifdef的Objective-C++(如果你只针对Mac OS,则不编译)
  2. Obj-C和C++都可以使用C接口,所以你可以用C编写一个适配器层(记住Obj-C是C的严格超集),并将其公开给dylib来调用C函数,然后由dylib调用Obj-C代码
  3. 您可以使用块,它在C、C++中工作,当然还有Obj-C
  4. 您可以包含objective-c运行时(请参阅文档),并对其进行处理(这是您将使用您提到的*IMP的地方)
  5. 另一种选择可能是从Cocoa端使用ObjectiveC++来设置C++对象,并将这些对象暴露给dylib。你将如何做到这一点实际上取决于图书馆是什么以及它是如何使用的等等;我们需要了解更多关于dylib的信息,以及它是如何被用来详细说明这一点的

既然您特别提到使用IMP,让我们更深入地讨论一下。声明是typedef void (*IMP)(id self, SEL _cmd, ...);,您可以看到它带有一个指向Obj-C对象的指针,以及一个SEL(选择器),它只是该方法的一个特殊的C字符串表示。您可以在文档中阅读有关SELIMP的更多信息。

您还可以使用运行时的C函数(如objc_msgSend),通过传递指向对象的指针和SEL来调用方法,就像传递IMP一样。

这些信息应该足以让你开始。感谢你的提问,顺便说一句,我以前从未真正坐下来思考过将C++与Objective-C结合的所有可能方法。很可能我错过了什么;)

您可以使用目标c运行时

include <objc/runtime.h>
objc_msgSend(id, SEL, arg0, ...)   

其中
id-是要发送消息的对象
SEL-是结构指针,描述您发送的消息
arg0,。。。是传递给选择器的参数。

有关运行时的更多了解,请参阅源代码http://www.opensource.apple.com/source/objc4/

您还可以强制转换IMP地址,并调用函数。

int(* foo)(id, SEL, arg) = IMP;
foo(someObject, @selector(someMessage), arg);