c++和objective c混编,回调函数不能用!!

tanxj 2010-09-25 10:14:10
之前发过一个帖子:http://topic.csdn.net/u/20100924/18/11f895bb-040b-41ee-ac68-9d040ae83995.html
//c++类:
typedef int (*MyMessagePtrType)( int); //回调函数

class ApplicationEngine : public IApplicationEngine {
public:
ApplicationEngine(MyMessagePtrType func);
~ApplicationEngine();
......
private:
......
MyMessagePtrType my_message_ptr;
};

IApplicationEngine* CreateApplicationEngine(MyMessagePtrType func)
{
return new ApplicationEngine(func);
}

ApplicationEngine::ApplicationEngine(MyMessagePtrType func):
{
my_message_ptr = func;
}

void ApplicationEngine::OnFingerDown(vec2 location, float elapsed)
{
int msg = 4;
if (my_message_ptr)
(*my_message_ptr)(msg); //这里直接用(*my_message_ptr)(4);的话,参数4送不过去。
//另外,用my_message_ptr(msg)的话,一样结果,不知道为什么还要加*??
}

objective-c 中的代码:
@interface GLView : UIView {

@private
BOOL m_pauseRender;
}

- (void) drawView: (CADisplayLink*) displayLink;//这个是objective-c类的一个回调
- (int) OnOpenGLMessage: (id) event Message: (int) msg; //这里的(id) fid 是自己在测试后加的,
//如果用- (int) OnOpenGLMessage: (int) msg;的话得不到传送过来的参数

@end

.....
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self
selector:@selector(drawView:)];//objective-c要送sel,不是送函数指针。(这个方便!)

m_applicationEngine = CreateApplicationEngine(
(MyMessagePtrType)[self methodForSelector:@selector(OnOpenGLMessage:Message:)]);//给函数指针到c++类
.....


- (void) drawView: (CADisplayLink*) displayLink //这个一点问题没有。
{
if (m_pauseRender) return;
......
}

- (int) OnOpenGLMessage: (id)event Message:(int) msg
{
NSLog(@"\n回调 %d\n", msg); //可以显示结果
switch (event) {
case 4:
m_pauseRender = YES;//程序在这里死掉
return 4;
break;
default:
break;
}
retrun 0; //不是4的话可以正常返回0
}
回调函数都没问题,就是在回调函数中使用GLView类中的成员时就死掉,到低是哪里没定义好还是其它问题。望各位大哥帮帮忙看看,万分感谢!!!
上次帖子中的zenny_chen兄,这次再要麻烦你了!!!!
...全文
1482 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
Proteas 2011-04-02
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 wsndbd 的回复:]

引用 21 楼 oexpress 的回复:

应该是没有问题的,GCC支持C++和OBJECT C混编译

支持混编,但是OC的类不能从C++派生,C++的类不能从OC派生
[/Quote]

第一,没人说需要互相派生。
第二,我的意思是为 Mac 平台实现一个特有的 IApplicationEngine ,只要接口保持一致就可以。
Proteas 2011-04-02
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 wsndbd 的回复:]

引用 20 楼 proteas 的回复:

通过继承来处理平台相关的特性应该可以吧?

现在不是平台相关性,是语言相关性
[/Quote]

看看 12 楼。
“TO:zenny_chen
问题是我那边的是一个纯c++类,传一个obj和sel 指针过去。以后要换成其它平台,那不又要改?”
wsndbd 2011-04-01
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 oexpress 的回复:]

应该是没有问题的,GCC支持C++和OBJECT C混编译
[/Quote]
支持混编,但是OC的类不能从C++派生,C++的类不能从OC派生
wsndbd 2011-04-01
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 proteas 的回复:]

通过继承来处理平台相关的特性应该可以吧?
[/Quote]
现在不是平台相关性,是语言相关性
CyberLogix 2011-04-01
  • 打赏
  • 举报
回复
应该是没有问题的,GCC支持C++和OBJECT C混编译
Proteas 2011-04-01
  • 打赏
  • 举报
回复
通过继承来处理平台相关的特性应该可以吧?
Proteas 2011-04-01
  • 打赏
  • 举报
回复
苹果机在公司,明天我也试试。
Proteas 2011-04-01
  • 打赏
  • 举报
回复


// code segment 1
void ApplicationEngine::OnFingerDown(vec2 location, float elapsed)
{
int msg = 4;
if (my_message_ptr)
(*my_message_ptr)(msg);
}

// code segment 2
m_applicationEngine = CreateApplicationEngine(
(MyMessagePtrType)[self methodForSelector:@selector(OnOpenGLMessage:Message:)]);



1、参考 http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

The instanceMethodForSelector: class method and the methodForSelector: instance method return a method implementation of type IMP。

// demo
BOOL (*test)(id, SEL, id);
test = (BOOL (*)(id, SEL, id))[target methodForSelector:@selector(isEqual:)];

// demo
typedef BOOL (*EqualIMP)(id, SEL, id);
EqualIMP test;
test = (EqualIMP)[target methodForSelector:@selector(isEqual:)];

while ( !test(target, @selector(isEqual:), someObject) ) {
...
}

基于上面的文档:
1、函数指针的声明要包含隐含参数。
2、这里真正的目标可能还不是为了简单的执行一段代码,而是为了告诉ObjC对象发生了一个事件。
就像 C++ 的非静态程序函数不能作为成员函数,但是可以通过 Thunk 技术,伪造一个调用栈,
用成员函数作为回调函数。但是此处我觉得你可能不是想这样。如果是想这样,只要将 id 与 SEL 设置为
NULL 调用这个函数就可以了。但是不知道运行时会不会检查参数。
3、我觉得解决这个问题的简单方法是:
在 C++ 的实现文件中包含 ObjC 的运行时头文件,主要是为了使用其中的一些类型定义。
然后,ApplicationEngine 的构造函数需要有 id 与 SEL,
回调函数需要参考上面的 demo 进行声明。
最后,使用 id ,SEL ,函数指针,调用 id 对象上的方法。
tanxj 2010-10-15
  • 打赏
  • 举报
回复
封装麻烦不?怎样做能给点提示不?谢谢!
txj1314211 2010-10-15
  • 打赏
  • 举报
回复
void* obj 传的是NSObject及其子类对象指针,不会有问题,如果不是,就会崩溃。
CreateBackCallManager(NSObject* obj, SEL selector);
tanxj 2010-10-15
  • 打赏
  • 举报
回复
封装是没做了,写了一个接口类:

#import <UIKit/UIKit.h>
#import "Interfaces.hpp"

class BackCallManager:public IBackCallManager {
public:
BackCallManager(void* obj, void* selector)
{
m_backObject = (NSObject*)obj;
m_selector = (SEL)selector;
}
int SendMessage(int msg) const
{
int er = (int)[m_backObject performSelector: m_selector withObject: (id)msg];
return er;
}
private:
NSObject* m_backObject;
SEL m_selector;
};

IBackCallManager* CreateBackCallManager(void* obj, void* selector)
{
return new BackCallManager(obj, selector);
}
IApplicationEngine* CreateApplicationEngine(IBackCallManager* backcallmanager)
//在这里把新类指针传给c++类,

zenny_chen兄:
用这方法回调没有问题,参数传送正常,但心里还是有点。。。
这样的类型转换不会有问题吧:void* obj -> (NSObject*)obj;
zenny_chen 2010-10-06
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 tanxj 的回复:]

TO:zenny_chen
问题是我那边的是一个纯c++类,传一个obj和sel 指针过去。以后要换成其它平台,那不又要改?
[/Quote]
呵呵,话说俺开发Mac OS X和iOS应用都不会去考虑兼容性之类的东西。
当然,这个问题也能解决。
你可以定义一个接口类,将NSObject和SEL指针封装起来。
tanxj 2010-10-06
  • 打赏
  • 举报
回复
TO:zenny_chen
问题是我那边的是一个纯c++类,传一个obj和sel 指针过去。以后要换成其它平台,那不又要改?
zenny_chen 2010-10-04
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hikaliv 的回复:]

这个问问 zenny_chen
[/Quote]
光宇啊,话说,你好久没来群里冒泡了。你妹妹也很长时间没来了,哈哈哈⋯⋯
FrankHB1989 2010-10-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 tanxj 的回复:]

在objective-c中我只知道《- (void) drawView 》最前面的"+"表示为类方法,"-" 表示实例方法;是否类方法就是c++中的非静态,而实例方法就是静态呢?
[/Quote]
看样子刚好反了。
C++的静态成员函数在一些语言中被称为静态方法或类方法,无法通过实例调用;C++的非静态成员函数在一些语言中被称为实例方法,可以通过实例调用。
zenny_chen 2010-10-03
  • 打赏
  • 举报
回复
m_applicationEngine = CreateApplicationEngine(
(MyMessagePtrType)[self methodForSelector:@selector(OnOpenGLMessage:Message:)]);//给函数指针到c++类

这个就有问题了。
你传一个selector是没用的。你必须把你这个selector所要操作的对象一起传进去。selector是需要对象或类去操作的。
所以,我认为你这边还是太平点,CreateApplicationEngine参数用SEL以及NSObject

IApplicationEngine* CreateApplicationEngine(SEL selector, NSObject *obj)
{
[obj performSelector:selector];
}

关于selector如何使用可以参考我的博客:
http://blog.csdn.net/zenny_chen/archive/2010/04/07/5457693.aspx
光宇广贞 2010-10-03
  • 打赏
  • 举报
回复
这个问问 zenny_chen
鸵鸟 2010-10-01
  • 打赏
  • 举报
回复
try using c style call
tanxj 2010-10-01
  • 打赏
  • 举报
回复
asuka:
try using c style call

啥意思?
hai040 2010-09-25
  • 打赏
  • 举报
回复
干脆只用C++不行?
不用一些特性就是object c
加载更多回复(4)

64,680

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧