RegisterGlobalProperty() with funcdef works correctly, what was missing in your code was the @. Here's an example on how to register a property with handle to a funcdef and assigning a function pointer to it.
engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
asIScriptFunction *f = 0;
engine->RegisterFuncdef("void myfunc()");
r = engine->RegisterGlobalProperty("myfunc @f", &f);
if( r < 0 )
TEST_FAILED;
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
"void func() {} \n");
mod->Build();
r = ExecuteString(engine, "@f = func; \n", mod);
if( r != asEXECUTION_FINISHED )
TEST_FAILED;
if( f == 0 )
TEST_FAILED;
if( strcmp(f->GetName(), "func") != 0 )
TEST_FAILED;
f->Release();
f = 0;
engine->Release();
When I said that casts for funcdefs work just like other casts, I meant in the script language. I.e, you can use the cast<type>(expr) operator on them. Here's a working example with both explicit and implicit casts:
engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
mod = engine->GetModule("mod", asGM_ALWAYS_CREATE);
mod->AddScriptSection("test",
"funcdef void myfunc1(); \n"
"funcdef void myfunc2(); \n"
"funcdef void myfunc3(); \n"
"bool called = false; \n"
"void func() { called = true; } \n"
"void main() \n"
"{ \n"
" myfunc1 @f1 = func; \n"
" myfunc2 @f2 = cast<myfunc2>(f1); \n" // explicit cast
" myfunc3 @f3 = f2; \n" // implicit cast
" assert( f1 is f2 ); \n"
" assert( f2 is f3 ); \n"
" assert( f3 is func ); \n"
" f3(); \n"
" assert( called ); \n"
"} \n");
r = mod->Build();
if( r < 0 )
TEST_FAILED;
r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
TEST_FAILED;
engine->Release();
Here's an example of a registered function that receives a function pointer:
bool receivedFuncPtrIsOK = false;
void ReceiveFuncPtr(asIScriptFunction *funcPtr)
{
if( funcPtr == 0 ) return;
if( strcmp(funcPtr->GetName(), "test") == 0 )
receivedFuncPtrIsOK = true;
funcPtr->Release();
}
//---------------------
r = engine->RegisterFuncdef("void AppCallback()");
r = engine->RegisterGlobalFunction("void ReceiveFuncPtr(AppCallback @)", asFUNCTION(ReceiveFuncPtr), asCALL_CDECL); assert( r >= 0 );
script =
"void main() \n"
"{ \n"
" AppCallback @func = @test; \n"
" func(); \n"
" ReceiveFuncPtr(func); \n"
"} \n"
"void test() \n"
"{ \n"
"} \n";
mod->AddScriptSection("script", script);
r = mod->Build();
if( r < 0 )
TEST_FAILED;
r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
TEST_FAILED;
if( !receivedFuncPtrIsOK )
TEST_FAILED;
I've confirmed that engine->RegisterObjectBehaviour("jjBEHAVIOR", asBEHAVE_IMPLICIT_REF_CAST, "DifferentFunctionPointer@ a()", asFUNCTION(0), asCALL_CDECL_OBJLAST); doesn't return an error. I'll have have that fixed.
I've now fixed this in revision 1657.