我的背景经验是C / C ++ / C#。
我在xcode项目中使用C ++库(具体来说,库是PJSIP)。要使用该库,我必须将几个回调连接到我的代码,如下所示:
#include < pjsua-lib/pjsua.h >
static void on_reg_state(pjsua_acc_id acc_id)
{
// Do work
}
static void Init()
{
// pjsua_config and psjua_config_default are defined in the header file from pjsip
pjsua_config cfg;
psjua_config_default(&cfg);
cfg.cb.on_regstate = &on_reg_state;
}
我想将此C ++ sytnax切换为Objective C
所以我做了:
+(void) on_reg_state:(pjsua_acc_id) acc_id
{
// Do work
}
+(void) Init
{
pjsua_config cfg;
psjua_config_default(&cfg);
cfg.cb.on_regstate = &on_reg_state; // ***** this is causing compile error
// I tried [CLASS NAME on_reg_state] and i get runtime error
}
我试图在Objective C中搜索委托,但我找不到类似的情况,其中回调已经在C ++中实现,并且您希望将它与Objective-C语法一起使用。
由于
答案 0 :(得分:2)
首先,根本不需要转换任何东西。从Objective-C调用C ++库是完全正确的。
其次,导致编译器错误的原因是你试图在一个应该有一个函数指针的地方粘贴一个方法。您不能使用&
运算符从Objective-C方法中生成函数指针。只需保留on_reg_state()
功能并像以前一样使用它,这就是你在Apple基于C语言的框架中进行回调的方式(当你超越高级Objective-C时,你需要这样做) API提供)。
第三,你的+ (void)Init
方法似乎有点奇怪。我强烈建议您不要写一个名为Init
(大写)的方法。如果您打算编写初始值设定项,则应为- (id)init
,即小写并返回id
。并且不要忘记调用其超类的指定初始值设定项,检查其返回值,将其分配给self,并在init
方法的末尾返回它(请参阅实现初始化程序在Apple's documentation,如果你不熟悉那个)。如果您的方法不是初始化程序,请使用其他名称,例如- (void)createConfig
。
答案 1 :(得分:0)
在这种情况下,您需要使用选择器。
+(void) on_reg_state:(pjsua_acc_id) acc_id
{
// Do work
}
+(void) Init
{
pjsua_config cfg;
psjua_config_default(&cfg);
cfg.cb.on_regstate_selector = @selector(on_reg_state:);
cfg.cb.target = self; //Self here is the class object in your 'Init' method, which is poorly named.
//Use this like [cfg.cb.target performSelector:cfg.cb.on_regstate_selector withObject:...etc]
}