Diego R [UPDATE] Touches TEST in Android crashes - Dynamic cast fails when inheriting from CCSprite
Posts 43
Added by Diego R over 1 year ago

After the latest Cocos changes where dynamic cast were introduced, I am having the following issue:

I declared:

class TouchSprite : public CCSprite, public CCTargetedTouchDelegate

and in the onEnter function I am doing:

void TouchSprite::onEnter() {
CCSprite::onEnter();
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true);
}

After tracing, I found that bool CCTouchHandler::initWithDelegate(CCTouchDelegate *pDelegate, int nPriority) fails in

(dynamic_cast<CCObject*>(pDelegate))->retain();

because the dynamic cast fails and returns NULL.

The code works fine when compiled using Xcode in iOS, but fails in Android. Any ideas?

  • Update: The touchesTest demo (which my code snippet is based on), crashes the same way in Android (runs fine in iPhone), I hope
    this makes it easier for the team to find the issue.

Thanks!

Minggo Zhang RE: [UPDATE] Touches TEST in Android crashes - Dynamic cast fails when inheriting from CCSprite
Posts 1641
Added by Minggo Zhang over 1 year ago

Yes, it crashed in (dynamic_cast<CCObject*>(pDelegate))->retain().
#926 is created for it.

Thank you.

Minggo Zhang RE: [UPDATE] Touches TEST in Android crashes - Dynamic cast fails when inheriting from CCSprite
Posts 1641
Added by Minggo Zhang over 1 year ago

I do the following test:

1. add

dynamic_cast<CCObject*>(this)->retain()
before
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true)

It also crashed at CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true).

2. change

class Paddle : public CCSprite, public CCTargetedTouchDelegate
to
class Paddle : public CCTargetedTouchDelegate, public CCSprite

It also crashed.

CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true) is called in other tests, but they are ok.
The difference is that Paddle inherits CCSprite, not CCLayer.

I don't know why.

Diego R RE: [UPDATE] Touches TEST in Android crashes - Dynamic cast fails when inheriting from CCSprite
Posts 43
Added by Diego R over 1 year ago

Hi Minggo,

Thanks for taking a look. The problem is that the way the paddle demo works is the cleanest way to track sprites touches.
Otherwise I'll have to pass all the touch handling to the scene object which is not a clen way to handle this.

Do we have any C++ wizards in the forums who can help?

Thanks!

Minggo Zhang RE: [UPDATE] Touches TEST in Android crashes - Dynamic cast fails when inheriting from CCSprite
Posts 1641
Added by Minggo Zhang over 1 year ago

In MenuTest.h, MenuLayer1 also invoke CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true), it works ok.
I change

class MenuLayer1 : public CCLayer

to
class MenuLayer1 : public CCLayer, public CCTextureProtocol

to make it inherits from multiple classes, it also works ok.

Both CCLayer and CCSprite inherit from multiple classes, and both of them inherit from CCNode.
So I think it is the matter with the content of CCSprite.

But I don't know why.
It is so strange, because it works ok in Paddle.cpp, but fails in CCTouchHandler.cpp.

Andre Rudlaff RE: [UPDATE] Touches TEST in Android crashes - Dynamic cast fails when inheriting from CCSprite
Posts 48
Added by Andre Rudlaff over 1 year ago

The problem is still there with CCKeypadDelegate.

I'm not sure on the perfect solution though.
In general rtti does not work over module boundaries: http://gcc.gnu.org/faq.html#dso (at least not in a safe and portable way)

I guess the reason why the layer approach works is, that CCKeypadDelegate (and CCTouchDelegate) are extended by CCLayer directly (i.e. library code).
While in the Paddle example the delegate is extendend by client code (i.e. in a different module).

So I guess there may be three solutions to this problem:
- compile game and library code into one single shared library (or statically link cocos2d and cocosdenshion)
- manually load the libraries using dlopen with the RTLD_GLOBAL flag (I havn't seen a way to add flags to the java call. Also this solution probably isn't really future-proof in case the internal file hierarchy changes)
- remove rtti from the library

Minggo Zhang RE: [UPDATE] Touches TEST in Android crashes - Dynamic cast fails when inheriting from CCSprite
Posts 1641
Added by Minggo Zhang over 1 year ago

We can not remove rtti, because we have to use multiple inherit.
I think the best way is to build cocos2dx into a static library.


(1-6/6)