Jump to content
  • Advertisement
Sign in to follow this  
_Sigma

Function pointer with unknown agrs??

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to create a wrapper class to automate some of the anglescript setup. I would like to be able to wrap this function:
	virtual int RegisterGlobalFunction(const char *declaration, const asUPtr &funcPointer, asDWORD callConv) = 0;
To use the RegisterGlobalFunction, you have to wrap the function address in a 'asFunction' macro like:

r = engine->RegisterGlobalFunction("void Print(string &in)", asFUNCTION(PrintString), asCALL_CDECL); assert( r >= 0 );


So I would like to somehow get rid of this, and automatically do this. My first go was this:
void TScript::ExposeFn( const std::string *declaration, const asUPtr &funcPointer )

but then I think I need the macro wrapper again. So I would really like something like:
void TScript::ExposeFn( const std::string *declaration, fnPtr &funcPointer )

where funcPointer could have any type of arguments and the underlying code would wrap the passed function in asFUNCTION and then pass it off to the angelscript function. I'm just not sure a)if this can be done b)how to any pointers would be great! Cheers

Share this post


Link to post
Share on other sites
Advertisement
I don't quite follow. Do you want to be able to call any function, given only a pointer to the function (void* or whatever), and a variable argument list (So essentially make the call yourself)? If so, you'll have to do some assembly to push the relevant parameters onto the stack.
One of the Game Programming Gems gooks has a bit about this in it somewhere (I'll look it out tonight if this is what you need)

Share this post


Link to post
Share on other sites
Ummm I dont see the problem, cant you just use templates?


template<typename FuncType>
void TScript::ExposeFn( const std::string *declaration, FuncType &funcPointer )




If you want more type safety then you can use boost.preprocessor to generate template overloads for each number of arguments garunteing that the passef in item is actually a function


template<typename R>
void TScript::ExposeFn( const std::string *declaration, R (&funcPointer)() )

template<typename R, typename T0>
void TScript::ExposeFn( const std::string *declaration, R (&funcPointer)(T0) )

template<typename R, typename T0, typename T1>
void TScript::ExposeFn( const std::string *declaration, R (&funcPointer)(T0, T1) )

// Or with BOOST_PP
#define GEN_OVERLOAD(z, n, data) \
template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(n, typename T)> \
void TScript::ExposeFn( const std::string *declaration, \
R (&funcPointer)(BOOST_PP_ENUM_PARAMS(n, T)) )

// generate overloads for 0-9 paramaters
BOOST_PP_REPEAT(10, GEN_OVERLOAD, ~)

#undef GEN_OVERLOAD


Share this post


Link to post
Share on other sites
I implemented Angelscript in my engine last week and did some macros for this.

#define ScriptFunction(returnType, function, usage) scriptEngine->RegisterGlobalFunction(#returnType" "#function#usage, asFUNCTION(function), asCALL_CDECL);


Example of usage:
// Define a function
int add(int x, int y)
{
return x + y;
}

int main()
{
// Make function available from the script
ScriptFunction(int, add, "(int, int)");

return 0;
}


I am not sure if it was exactly this way you use it. But you see the idea anyway. I also added support for member functions. You can look at my code here if you want to: http://openfury.svn.sourceforge.net/viewvc/openfury/trunk/include/engine/scriptmacros.h?view=markup

Share this post


Link to post
Share on other sites
Oh ok i just read what Klarre wrote, if thats what you want then id utilize the type system.


// traits class to give the name of a type as a string
template<typename T>
struct script_func_traits
{
static const char* type_name;
};

template<typename T>
const char* script_func_traits<T>::type_name = typeid(T).name();

// specialize for built in types and any classes you want to use
#define SCRIPT_FUNC_TRAITS_SPECIALIZATION(type) \
template<> \
struct script_func_traits<type> \
{ \
static const char* type_name; \
}; \
\
template<> \
const char* script_func_traits<type>::type_name = #type

SCRIPT_FUNC_TRAITS_SPECIALIZATION(int)
SCRIPT_FUNC_TRAITS_SPECIALIZATION(unsigned int)
SCRIPT_FUNC_TRAITS_SPECIALIZATION(char)
SCRIPT_FUNC_TRAITS_SPECIALIZATION(long)
// ...

#undef SCRIPT_FUNC_TRAITS_SPECIALIZATION

// function that takes the function name and function pointer and registers it
#define GEN_REGISTER_FUNCTION(z, n, _) \
template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(n, typename T)> \
void register_function(const std::string& name, \
R (&func)(BOOST_PP_ENUM_PARAMS(n, T))) \
{ \
/* construct the prototype string "R name(T0, T1, ..., Tn)" */ \
std::string prototype = script_func_traits<R>::type_name + \
(" " + name) + "(" + \
BOOST_PP_ENUM_BINARY_PARAMS \
( n, \
script_func_traits<T,>::type_name + "," + BOOST_PP_INTERCEPT \
) \
")"; \
r = engine->RegisterGlobalFunction(prototype.c_str(), \
asFUNCTION(func), \
asCALL_CDECL); \
assert( r >= 0 ); \
}

/* genrate overloads for functions with 0 - 9 paramaters */
BOOST_PP_REPEAT(10, GEN_REGISTER_FUNCTION, ~)

#undef GEN_REGISTER_FUNCTION

/* utility macro */
#define REGISTER_SCRIPT_FUNCTION(function) \
register_function(#function, function)





Edit: Fixed the errors Deyja mentioned. You might be able to overcome the differences in type names by editing SCRIPT_FUNC_TRAITS_SPECIALIZATION to take the name of the type in AngelScript but im not sure because ive never used it.

[Edited by - Julian90 on April 20, 2007 6:52:26 AM]

Share this post


Link to post
Share on other sites
You should have posted this in the AngelScript forums.

Why, exactly, is invoking asFUNCTION so dreaded? This seems to be a lot of over-engineered fluff to avoid one little macro which you just end up invoking anyway. Julian90's implementation is interesting in that it seems to be building the signature string on the fly. Except that it doesn't put a space between the return type and the function name, and doesn't put any commas in the argument list. Unfortunately, it wouldn't work, because the names of AngelScript types aren't the same as the names in C++.

Share this post


Link to post
Share on other sites
Quote:
Do you want to be able to call any function, given only a pointer to the function (void* or whatever), and a variable argument list (So essentially make the call yourself)?

I think that kinda was the plan...somewhat combined with what Klarre is doing, but without macros.

Quote:
You should have posted this in the AngelScript forums.

Sorry, I felt it was more suited to general programming as it is more of a programming question.

Quote:

Why, exactly, is invoking asFUNCTION so dreaded?

I have no idea! Actually I do - it isn't. I just thought it would be something cool to be able to do, but it appears pretty intense with *a lot* of overhead bloat, which I don't really want. I think I might just go with:


void TScript::ExposeFn( const std::string *declaration, const asUPtr &funcPointer )

//call it
script->ExposeFn("int print(int, int)",asFUNCTION(myfn));




I would still be very interested in seeing evil steve's method. Is this the way that printf handles the multiple arguments?

PS. I'm sorry for my slight incoherence above. I guess it was just too early in the morning...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!