I'm trying to allow scripts to get function pointers by passing a string with the CDECL, and found out that, when we use GetFunctionByDecl to try to get the pointer of a function inside a namespace, if that function receives parameters, GetFunctionByDecl returns NULL.
Lemme explain with code:
So, here is the code to register "Get function pointer":
r = engine->RegisterGlobalFunction ("void getFuncPtr (const string &in)", asFUNCTION (getFuncPtr), asCALL_CDECL); assert (r >= 0);
Please notice that currently, the getFuncPtr function is not actually returning anything (as it's return type is void); I'll get into that in the second issue, but for now, let me first explain the problem with namespaces.
the code for getFuncPtr goes like this:
void getFuncPtr (const string &Name)
{
asIScriptFunction *Func = engine->GetModule(0)->GetFunctionByDecl (Name.c_str ());
cout << Name << endl;
cout << Func << endl;
cout << Func->GetObjectType () << endl;
}
And, in an angelscript we have the following code:
void DoNothing (int NotUsed)
{
}
namespace Freedom
{
void DoNothing ()
{
}
void DoNothingElse (int NotUsed)
{
}
}
void main ()
{
getFuncPtr ("void DoNothing (int)");
getFuncPtr ("void Freedom::DoNothing ()");
getFuncPtr ("void Freedom::DoNothingElse (int)");
}
and that code prints the following:
main.fss (0, 0) : INFO : Script successfully built
void DoNothing (int)
005BA9D0
00000000
void Freedom::DoNothing ()
005BAB28
00000000
void Freedom::DoNothingElse (int)
00000000
Notice that, for the first 2 calls to getFuncPtr, we get a pointer, but for the third, the one that tries to get the address of the function that receives parameters and is inside a namespace, we get NULL. Of course, the application crashes in the third call to getFuncPointer, since we got a NULL pointer.
Another thing that worries me is that "Func->GetObjectType ()" is always returning NULL.
So, that's for the first issue: getting functions with parameters inside namespaces.
======================================================
Of course, the main idea behind all of this weirdness is to allow script objects to get pointers to functions (I know, it's weird...), so, after lots of not-less-weird attempts, I tried with the ref object:
//Register the function to return a ref:
r = engine->RegisterGlobalFunction ("ref @getFuncPtr (const string &in)", asFUNCTION (getFuncPtr), asCALL_CDECL); assert (r >= 0);
//some happy lines of code later...
CScriptHandle *getFuncPtr (const string &Name)
{
CScriptHandle *Handle = new CScriptHandle;
asIScriptFunction *Func = engine->GetModule(0)->GetFunctionByDecl (Name.c_str ());
cout << Name << endl;
cout << Func << endl;
cout << Func->GetObjectType () << endl;
Handle->Set (Func, Func->GetObjectType ());
return Handle;
}
and the script is pretty the same code as the previous. If I'm lucky, the output goes something like this:
main.fss (0, 0) : INFO : Script successfully built
System function (1, 1) : ERR : Expected data type
00000000
notice that for "Name" is not printing anything, so, the function is not actually getting the correct reference. Of course, the application crashes
(On an unlucky run, I would get a matrix screen saver in my console output)
I'ts most likely just me doing something stupid; I gotta admit I don't understand this "reference object" very much .