Advertisement

Script sees a global variable as null pointer

Started by September 12, 2011 06:23 AM
5 comments, last by osiris_dev 13 years, 2 months ago
Hi all,

There is a small problem. I registered a few global properties.



static LPGameProcessGUI g_TE3GameProcGUICurrent = NULL;

static LPGameProcessGUI GetGUIProcContext()
{
return g_TE3GameProcGUICurrent;
}


r = asScriptEngine->RegisterGlobalProperty("CTE3GameProcessGUI@ g_TE3GameProcGUICurrent", &g_TE3GameProcGUICurrent); assert( r >= 0);
r = asScriptEngine->RegisterGlobalFunction("CTE3GameProcessGUI@ GetGUIProcContext()", asFUNCTION(GetGUIProcContext), asCALL_CDECL ); assert( r >= 0);




and singleton


class CTE3ScriptManager
{
protected:
static CTE3ScriptManager m_ScriptManager;

CTE3ScriptManager();

public:
virtual ~CTE3ScriptManager(void);


static CTE3ScriptManager& Get() { return m_ScriptManager; }
};

// registry inside class
r = m_asScriptEngine->RegisterGlobalProperty("CTE3ScriptManager ScriptManager", this); assert( r >= 0);


Inside my script I get null pointer for variables, although in C + + debugger all variables are initialized.


string strButtonName = "_lv_ButtonName";

// ScriptManager - thi null
strButtonName = ScriptManager.GetScriptContextValuesLocal().GetValueNameString(string("_lv_ButtonName"));

CTE3CIIScreen @pMainScreen = null;

// or this null
@pMainScreen = GetGUIProcContext().GetMainScreen();


AngelScript Runtime: gui_proc_change_screen.as: Null pointer access . line: 6. column: 2

What's wrong?
I need to see a little more of the code.

The script is giving a null pointer access at line 6, column 2. But which line in the script is this actually referring to?

The [color="#660066"]GetGUIProcContext function doesn't increase the reference counter of the returned handle. If the object is really reference counted, then this would cause the code to release the object before you actually wanted it.

The global variable [color="#000000"]g_TE3GameProcGUICurrent can obviously be null at times. What would these times be?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
That's how I register the class itself


// GUI Game Processor

r = asScriptEngine->RegisterObjectType("CTE3GameProcessGUI", 0, asOBJ_REF ); assert( r >= 0 );

r = asScriptEngine->RegisterObjectBehaviour("CTE3GameProcessGUI", asBEHAVE_ADDREF, "void f()", asFUNCTION(RegisterScriptNullFunc<CTE3GameProcessGUI>), asCALL_CDECL_OBJLAST); assert( r >= 0 );
r = asScriptEngine->RegisterObjectBehaviour("CTE3GameProcessGUI", asBEHAVE_RELEASE, "void f()", asFUNCTION(RegisterScriptNullFunc<CTE3GameProcessGUI>), asCALL_CDECL_OBJLAST); assert( r >= 0 );

r = asScriptEngine->RegisterObjectMethod("CTE3GameProcessGUI", "CTE3CIIScreen@ GetMainScreen()", asMETHOD(CTE3GameProcessGUI,GetMainScreen), asCALL_THISCALL); assert( r >= 0 );
r = asScriptEngine->RegisterObjectMethod("CTE3GameProcessGUI", "TE3CIIAccessor@ GetMainAccessor()", asMETHOD(CTE3GameProcessGUI,GetMainAccessor), asCALL_THISCALL); assert( r >= 0 );
r = asScriptEngine->RegisterObjectMethod("CTE3GameProcessGUI", "CTE3CIIScreenManager@ GetScreenManager()", asMETHOD(CTE3GameProcessGUI,GetScreenManager), asCALL_THISCALL); assert( r >= 0 );


Singleton registry


r = m_asScriptEngine->RegisterObjectType("CTE3ScriptManager", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( r >= 0);

r = m_asScriptEngine->RegisterGlobalProperty("CTE3ScriptManager ScriptManager", this); assert( r >= 0);

r = m_asScriptEngine->RegisterObjectMethod("CTE3ScriptManager", "CTE3ScriptValuesVault@ GetScriptContextValuesLocal()", asMETHOD(CTE3ScriptManager,GetScriptContextValuesLocal), asCALL_THISCALL); assert( r >= 0);
r = m_asScriptEngine->RegisterObjectMethod("CTE3ScriptManager", "CTE3ScriptValuesVault@ GetScriptContextValuesGlobal()", asMETHOD(CTE3ScriptManager,GetScriptContextValuesGlobal), asCALL_THISCALL); assert( r >= 0);


Empty ref counter functions. I saw it in this forum.


template <class T> void RegisterScriptNullFunc(T* ptr){}


As for the error, I just gave an example of the type of error. It is always the same, and it happens in a situation calling ScriptManager or g_TE3GameProcGUICurrent or GetGUIProcContext ()

Full script code with comments


//
void main_change_screen()
{
string strButtonName = "_lv_ButtonName";

// now error is here
strButtonName = ScriptManager.GetScriptContextValuesLocal().GetValueNameString(string("_lv_ButtonName"));

CTE3CIIScreen @pMainScreen = null;

// but it may happen here
@pMainScreen = GetGUIProcContext().GetMainScreen();
// and here
@pMainScreen = g_TE3GameProcGUICurrent.GetMainScreen();
if( pMainScreen is null )
return;

//
TE3CIIAccessor@ pMainAccessor = g_TE3GameProcGUICurrent.GetMainAccessor();
if( pMainAccessor is null )
return;

//
// string strButtonName = ScriptManager.GetScriptContextValuesLocal().GetValueNameString(string("_lv_ButtonName"));

CDX9E3DSGUIControlButton@ pButton = pMainAccessor.GetControlButtonName(strButtonName);

//
if( pButton.GetState() != SGUI_BUTTON_STATE_DOWN ||
!g_TE3GameProcGUICurrent.GetScreenManager().Delay( 300 ) )
return;

//
CTE3CIIScreen@ pTargetScreen = g_TE3GameProcGUICurrent.GetScreenManager().FindScreenForName( string("_lv_TagerScreenName") );
if( pTargetScreen is null )
return;

//
if( pTargetScreen.GetVisible() )
return;

//
g_TE3GameProcGUICurrent.GetScreenManager().SetActiveScreenName( pTargetScreen.GetScreenName() );
}


These variables are not exactly zero, I checked their values before calling the script.

Thanks for your help.
I made ??a small test.


// declare variable

static int g_iTest = 1;
// registry

r = asScriptEngine->RegisterGlobalProperty("int g_iTest", &g_iTest); assert( r >= 0);



Before call script made: g_iTest = 2; But in script context variable value still 1.
That's works



r = m_asScriptEngine->RegisterGlobalProperty("CTE3ScriptManager ScriptManager", &m_ScriptManager); assert( r >= 0);




All global variables are placed in single classes now.
Seems you've solved your problem, but I didn't quite get the change you did.

It looks like the cause may have been registering the property with a variable that became invalid before it was used. Is that it?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
The problem was that I register the static variables in Angel Script, then in C + +, I changed their meaning. But the script remained the initial value obtained at registration.

Singleton case differs only in that I register the final value of the variable in the script.

This topic is closed to new replies.

Advertisement