C++函数调用作为参数,而不是工作
http://pastebin.com/CsViwQFg 我使用的是被称为DragonFireSDK的SDK,并有一个名为TouchAdd(),它可以让我补充一个函数作为参数(在这种情况下功能:MoveLeft()和MoveRight的())。 唯一的问题是,如果函数是一个类(在这种情况下,播放器类),我收到以下错误:C++函数调用作为参数,而不是工作
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);
}
错误:
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
tleft = TouchAdd(0,0,180,480,player->MoveLeft,0);
tright = TouchAdd(180,0,180,480,player->MoveRight,0);
你'不传递MoveLeft
和MoveRight
函数的参数。我想他们是函数调用,因为你的主题的标题说,所以你必须通过参数,如果他们采取论据。
如果他们不采取说法,那么这样做:
tleft = TouchAdd(0,0,180,480,player->MoveLeft(),0);
tright = TouchAdd(180,0,180,480,player->MoveRight(),0);
如果他们不函数调用,而不是你想通过成员函数指针,然后执行以下操作:
tleft = TouchAdd(0,0,180,480, &Player::MoveLeft,0);
tright = TouchAdd(180,0,180,480, &Player::MoveRight,0);
您还需要传递该实例,以便稍后可以调用成员函数。
如果你让我们知道TouchAdd
函数的签名会更好。这样我们可以更具体地回答。
如果您想将函数作为参数传递,则语法为&Player::MoveLeft;
,因为它不绑定到任何对象,如player
。
DragonFireSDK似乎想要一个“C”可调用函数,并且您试图传递一个成员函数(尽管不使用正确的语法)。我认为你需要做的是这样:
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);
}
注意,即使一个静态成员函数往往会工作(因为没有“隐藏” this
指针传递中,严格来说,你应该使用非成员extern "C"
功能。
正如有人在现在删除的评论中提到的那样,“id '参数可能有足够的信息来查找目标'Player'对象 - 可能通过将这些DragonFire ID的映射保存到'Player'对象。我对DragonFireSDK的了解不够多,不足以推测。 – 2011-04-14 05:35:08
由于(从here截取)的TouchAdd
函数签名是
int TouchAdd(int x, int y, int width, int height, int (*callback)(int id, int event, int x, int y), int id);
预期功能必须是自由功能,例如:
int myCallback(int id, int event, int x, int y){
// do your stuff
}
void AppMain(){
tLeft = TouchAdd(....,&myCallback,...);
}
不能传递一个成员函数的指针(&Player::MoveX
),因为该功能需要与类(Player
)的对象上被调用。所以,你需要使用一个变通为:
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,...);
}
}
好像id
是被传递给回调的自定义参数。如果你只有32位目标(而且DragonFireSDK似乎只适用于iPhone,所以我猜答案是肯定的),你可以将它转换为Player *绑定到播放器实例。
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);
}
即使不工作,或者你不想使用有点丑陋的类型转换,你可以随时与查找表全局或静态对象。使PlayerMoveLeft和PlayerMoveRight Player类的静态成员也可能看起来更好,我认为它应该在TouchAdd()中表现良好。
您可能会发现需要静态函数(取决于我认为的接口定义) – forsvarir 2011-04-14 05:06:45
TouchAdd函数的签名是什么?例如,函数的参数是什么类型? – Xeo 2011-04-14 05:06:55