C ++函数调用作为参数,不起作用

时间:2011-04-14 04:56:10

标签: c++

http://pastebin.com/CsViwQFg 我正在使用名为DragonFireSDK的SDK,并且有一个名为TouchAdd()的函数,我可以添加一个函数作为参数(在这种情况下:MoveLeft()和MoveRight())。 唯一的问题是,如果函数在类中(在本例中是Player类),我会收到以下错误:

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

5 个答案:

答案 0 :(得分:2)

如果要将函数作为参数传递,则语法为&Player::MoveLeft;,因为它不绑定到任何对象,例如player

答案 1 :(得分:2)

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"函数。

答案 2 :(得分:1)

由于TouchAdd的函数签名(取自here)是

int TouchAdd(int x, int y, int width, int height, int (*callback)(int id, int event, int x, int y), int id);

预期函数必须是 free 函数,例如:

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,...);
}

}

答案 3 :(得分:1)

似乎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()一起使用。

答案 4 :(得分:0)

tleft = TouchAdd(0,0,180,480,player->MoveLeft,0);
tright = TouchAdd(180,0,180,480,player->MoveRight,0);

您不会将参数传递给MoveLeftMoveRight函数。我认为它们是函数调用,因为你的主题的标题是,所以你必须传递参数,如果他们接受参数。

如果他们不接受争论,那就这样做:

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函数的签名会更好。这样我们就可以更具体地回答。