http://pastebin.com/CsViwQFg I'm using an SDK known as DragonFir开发者_如何学CeSDK and there's a function called TouchAdd() that let's me add a function as a parameter (in this case: MoveLeft() and MoveRight()). The only problem is, if the function is in a class (in this case, the Player class), I get the following errors:
Player *player;
void AppMain()
{
player = new Player(20,20,10);
tleft = TouchAdd(0,0,180,480,player->MoveLeft,0);
tright = TouchAdd(180,0,180,480,player->MoveRight,0);
}
The error:
error C3867: 'Player::MoveLeft': function call missing argument list; use '&Player::MoveLeft' to create a pointer to member
error C3867: 'Player::MoveRight': function call missing argument list; use '&Player::MoveRight' to create a pointer to member
If you want to pass function as a parameter then syntax is &Player::MoveLeft;
as it is not bound to any object such as player
.
The DragonFireSDK appears to want a "C" callable function and you're trying to pass a member function (though not using the right syntax). I think you'll need to do something like:
Player *player;
extern "C"
int PlayerMoveLeft(int id, int event, int x, int y)
{
// do something - I'm not sure what might be possible
// to get a pointer or a reference to the player object
// hopefully one or more parameters passed to this callback
// will have the information you need to do that
// or if you only have one global player, you're set -
// just use it
Player* player = /* ??? */;
player->MoveLeft( id, event, x, y); // or whatever needs to be passed
return 0;
}
extern "C"
int PlayerMoveRight(int id, int event, int x, int y)
{
Player* player = /* ??? */;
player->MoveRight( id, event, x, y); // or whatever needs to be passed
return 0;
}
void AppMain()
{
player = new Player(20,20,10);
tleft = TouchAdd(0,0,180,480,PlayerMoveLeft,0);
tright = TouchAdd(180,0,180,480,PlayerMoveRight,0);
}
Note that even though a static member function will often work (since there's no 'hidden' this
pointer passed in, strictly speaking you should use non-member extern "C"
functions.
Since the function signature of TouchAdd
(taken from here) is
int TouchAdd(int x, int y, int width, int height, int (*callback)(int id, int event, int x, int y), int id);
the expected function must be a free function, eg:
int myCallback(int id, int event, int x, int y){
// do your stuff
}
void AppMain(){
tLeft = TouchAdd(....,&myCallback,...);
}
You can't pass a member function pointer (&Player::MoveX
), since that function needs to be called on an object of that class (Player
). So you need to use a work-around for that:
Player* player;
int PlayerMoveLeft(int id, int event, int x, int y){
return player->MoveLeft(id,event,x,y);
}
int PlayerMoveRight(int id, int event, int x, int y){
return player->MoveRight(id,event,x,y);
}
void AppMain(){
player = new Player(20,20,10);
tLeft = TouchAdd(...,&PlayerMoveLeft,...);
tRight = TouchAdd(...,&PlayerMoveRight,...);
}
}
It seems like id
is the custom parameter that gets passed to the callback. If you only have 32-bit targets (and it seems like DragonFireSDK is meant only for iPhone, so I guess the answer is yes), you can cast it to Player* to bind to the player instance.
int PlayerMoveLeft(int id, int event, int x, int y)
{
Player* player = reinterpret_cast<Player*>(id);
return player->MoveLeft(event, x, y);
}
int PlayerMoveRight(int id, int event, int x, int y)
{
Player* player = (Player*)id;
return player->MoveRight(event, x, y);
}
void AppMain()
{
Player* player = new Player(20,20,10);
tleft = TouchAdd(0,0,180,480,PlayerMoveLeft,(int)player);
tright = TouchAdd(180,0,180,480,PlayerMoveRight,(int)player);
}
Even if that doesn't work, or you don't want to use kinda-ugly type casts, you can always have a global or static object with lookup tables. Making PlayerMoveLeft and PlayerMoveRight static members of the Player class may also look nicer, and I think it should play well with TouchAdd().
tleft = TouchAdd(0,0,180,480,player->MoveLeft,0);
tright = TouchAdd(180,0,180,480,player->MoveRight,0);
You're not passsing arguments to MoveLeft
and MoveRight
functions. I suppose they're function call as the title of your topic says, so you must pass arguments as well IF they take arguments.
If they're don't take argument, then do this:
tleft = TouchAdd(0,0,180,480,player->MoveLeft(),0);
tright = TouchAdd(180,0,180,480,player->MoveRight(),0);
If they're NOT function calls, instead you want to pass the member function pointers, then do this:
tleft = TouchAdd(0,0,180,480, &Player::MoveLeft,0);
tright = TouchAdd(180,0,180,480, &Player::MoveRight,0);
You also need to pass the instance so that member functions can be invoked later on.
It would be better if you let us know the signature of TouchAdd
function. So that we can answer more specifically.
精彩评论