Called function from AS crashes

This topic is 3837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

This is bollocks. I can post everywhere but here! Alright, hopefully this works! I am going to link to my issue, as posting long posts doesn't seem to work for me? Error Thanks guys! and yes GD hates me :( [Edited by - _Sigma on July 16, 2007 4:58:29 PM]

Share on other sites
_Sigma, I think you're posts are cursed here on gamedev.
either that or the server just doesn't like you. :P

Share on other sites
oooh, witchlord, you have Sigma-itous!

maybe it's something with the forum?

Share on other sites
Yeah, yesterday I tried to make a post out of your attachment (for easier reading and also out of curiousity as to why you weren't able to post it). It seems there is something in that post that makes the GameDev.net forum code fail to process it. I couldn't even do a preview of it.

Well, going back to your problem. Can you show me how you have registered the string class your using, and the exact way you're registering the IsKeyDown() method?

Something is going wrong when the IsKeyDown() method is being called. AngelScript isn't calling the method the way C++ is expecting it to be called. There can be a few different reasons for that, 1) The string type has not been properly registered, 2) The IsKeyDown() method isn't registered correctly, 3) A bug in AngelScript.

Regards,
Andreas

Share on other sites
I am using your scriptstring, so it is used as per your examples:
	//add check here	RegisterScriptString(m_engine);
, where RegisterScriptString is in scriptstring.cpp which is provided by the SDK.

This is called before anything else is registered, etc.

I can use strings in other functions, so I doubt that this is the problem. As well, when I trace into the IsKeyDown() method, the string parameter is set correctly.

IsKeyDown() is register like thus:

m_script.RegisterObject("TInput"); 	m_script.RegisterObjectMethod("TInput","bool IsKeyDown(const string &key)",asMETHOD(TInput,IsKeyDown)); 	m_script.RegisterAsGlobal("TInput Input",(void*)&m_input);

those corresponding fuctions are below:
void TScript::RegisterObject( std::string declaration,int size/*=0*/,asDWORD flags/*=0*/ ){	int r = m_engine->RegisterObjectType(declaration.c_str(),size,flags);	r < 0 ? throw TFatalException("Failed to register object" + declaration + " with Angel Script. \n\n In:\n TScript::RegisterObject") : ++r;}void TScript::RegisterObjectMethod( std::string obj, std::string declaration, asUPtr fnPtr){	int r = m_engine->RegisterObjectMethod(obj.c_str(),declaration.c_str(),fnPtr,asCALL_THISCALL);		r < 0 ? throw TFatalException("Failed to register object method " + declaration + " with Angel Script. \n\n In:\n TScript::RegisterObjectMethod") : ++r;}void TScript::RegisterAsGlobal( std::string declaration, void* ptr ){	if(ptr)	{		int r = m_engine->RegisterGlobalProperty(declaration.c_str(),ptr);		r < 0 ? throw TFatalException("Failed to register global property" + declaration + " with Angel Script. \n\n In:\n TScript::RegisterGloalProperty") : ++r;	}	else	{		throw TFatalException("Failed to register global property " + declaration + " with Angel Script. Reason: Void function pointer. \n\n In:\n TScript::RegisterGloalProperty");	}}

One thing, and I'm not sure if this is an issue, but I'll raise it just in case.

On the line m_script.RegisterAsGlobal("TInput Input",(void*)&m_input);
, m_input is a member variable of TKernel. So I'm trying to register a member var of TKernel with AS, from within a TKernel instance. I haven't had issues with this in the past, but I felt I should bring it to your attention in case it is an issue, and I've just gotten lucky previously.

It should also be noted I'm using the newest build 2.8.1 off your website.

Thanks!

Share on other sites
The fact that m_input is a member of TKernel shouldn't be a problem, as long as TKernel is alive the whole time while the script engine has access to the pointer.

I cannot find any obvious error in the code you've shown me. I'll have to make some tests to make sure this works properly in AngelScript, though I'm pretty sure I've got a test case that matches your code.

When you debug your code, can you verify if the this pointer in IsKeyDown is valid? That seems to be the next most likely problem. Either the pointer you registered with RegisterGlobalProperty is not valid, or AngelScript is somehow deciding to modify it before calling the method.

By the way, is TKernel::m_input a pointer to a TInput class? Or is it an embedded class?

Share on other sites
Quote:
 ...as long as TKernel is alive the whole time while the script engine has access to the pointer.
Yup.
Quote:
 By the way, is TKernel::m_input a pointer to a TInput class? Or is it an embedded class?
Pointer. Only the one instance.

Quote:
 When you debug your code, can you verify if the this pointer in IsKeyDown is valid?

As my test code, I call IsKeyDown from the main c++ loop, then call it from my script. So it's called twice per game loop. The C++ call works fine, the AS call doesn't.

C++ call
this = 0x003c72f0
-		this	0x003c72f0 {m_keys=[4]((18305857,208 'Ð'),(67569141,205 'Í'),(1737434130,203 'Ë'),(2499999305,200 'È')) m_shiftState=true m_altState=true ...}	Tempest::TInput * const+		m_keys	[4]((18305857,208 'Ð'),(67569141,205 'Í'),(1737434130,203 'Ë'),(2499999305,200 'È'))	std::map<unsigned long,unsigned char,std::less<unsigned long>,std::allocator<std::pair<unsigned long const ,unsigned char> > >		m_shiftState	true	bool		m_altState	true	bool		m_inited	true	bool+		m_kbstate	0x003c730f ""	unsigned char [256]+		m_dxInput	0x00166dc4	IDirectInputA *+		m_keyboard	0x0015b814	IDirectInputDeviceA *+		m_hWnd	0x00060bf8 {unused=??? }	HWND__ *+		m_hInstance	0x00400000 {unused=9460301 }	HINSTANCE__ *

Script call
this = 0x003c39ec
-		this	0x003c39ec {m_keys=[0]() m_shiftState=true m_altState=false ...}	Tempest::TInput * const		m_keys	[0]()	std::map<unsigned long,unsigned char,std::less<unsigned long>,std::allocator<std::pair<unsigned long const ,unsigned char> > >		m_shiftState	true	bool		m_altState	false	bool		m_inited	true	bool+		m_kbstate	0x003c3a0b ""	unsigned char [256]+		m_dxInput	0xfeeefeee	IDirectInputA *+		m_keyboard	0x00000000	IDirectInputDeviceA *+		m_hWnd	0x00000000 {unused=??? }	HWND__ *+		m_hInstance	0x000c0016 {unused=??? }	HINSTANCE__ *

So this changed what it was pointing to...that isn't supposed to happen correct?

Share on other sites
Quote:

Quote:
 By the way, is TKernel::m_input a pointer to a TInput class? Or is it an embedded class?

Pointer. Only the one instance.

Aha!! That's the problem. The TInput global property should be registered as:

 	m_script.RegisterAsGlobal("TInput Input",(void*)m_input);

RegisterGlobalProperty() is expecting a pointer to the object, not a pointer to a pointer to the object as you were giving it.

Let me know if the problem persists after changing this.

Share on other sites

Everything works now!

So, you don't charge for tech support eh Andreas? ;) I think I'd owe you a fortune now! Thanks a *ton* for all the help!

Share on other sites
If I did charge for tech support nobody would use AngelScript. ;)

I'm glad it worked out. I look forward to seeing what you'll do with AS.

Share on other sites
Quote:
 Original post by _SigmaI had added that & as per here. Everything works now! So, you don't charge for tech support eh Andreas? ;) I think I'd owe you a fortune now! Thanks a *ton* for all the help!

To defend myself:
* I was wrong when I told you to use &m_input -- I was thinking about my code where I had the value itself, and not a pointer.

* Later on in that thread, I used "&Get()" to register - this is because Get returned a reference and not a pointer.

Share on other sites
Quote:
Original post by midnite
Quote:
 Original post by _SigmaI had added that & as per here. Everything works now! So, you don't charge for tech support eh Andreas? ;) I think I'd owe you a fortune now! Thanks a *ton* for all the help!

To defend myself:
* I was wrong when I told you to use &m_input -- I was thinking about my code where I had the value itself, and not a pointer.

* Later on in that thread, I used "&Get()" to register - this is because Get returned a reference and not a pointer.

Hey no worries man! I wasn't paying as much attention as I should have, and I should have seen that since I was using a ptr, that this wasn't the right way! Ah well, c'est la vie!