C ++类成员函数指针到函数指针 [英] C++ class member function pointer to function pointer

查看:215
本文介绍了C ++类成员函数指针到函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将luabind用作C ++包装器的lua. Luabind提供了一种使用我自己的回调函数来处理lua抛出的异常的方法set_pcall_callback().因此,我从文档中解释了一个示例,所做的更改是logger-> log()函数,并将该函数放置在名为"Engine"的类中,因此,它不再是常规的全局函数,而现在是成员函数,即我的问题似乎在哪里.

I am using luabind as my lua to C++ wrapper. Luabind offers a method to use my own callback function to handle exceptions thrown by lua, set_pcall_callback(). So I paraphrased an example from the documentation, the changes being the logger->log() function and putting the function in a class called 'Engine', so instead of it being a regular global function it is now a member function, which is where my problem seems to be.

以下是相关的代码片段:

Here are the relevant code snips:

class Engine //Whole class not shown for brevity
{
public:
    Engine();
    ~Engine();
    void Run();
    int pcall_log(lua_State*);
private:
    ILogger *logger;
};

Engine::Run()
{
lua_State* L = lua_open();
luaL_openlibs(L);
open(L);
luabind::set_pcall_callback(&Engine::pcall_log); //<--- Problem line
//etc...rest of the code not shown for brevity
}

int Engine::pcall_log(lua_State *L)
{
lua_Debug d;
lua_getstack( L,1,&d);
lua_getinfo( L, "Sln", &d);
lua_pop(L, 1);
stringstream ss;
ss.clear();
ss.str("");
ss << d.short_src;
ss << ": ";
ss << d.currentline;
ss << ": ";
if ( d.name != 0)
{
    ss << d.namewhat;
    ss << " ";
    ss << d.name;
    ss << ") ";
}
ss << lua_tostring(L, -1);
logger->log(ss.str().c_str(),ELL_ERROR);
return 1;
}

这是编译器在编译过程中所说的:

Here is what the compiler says during compilation:

C:\pb\engine.cpp|31|error: cannot convert 'int (Engine::*)(lua_State*)' to 'int (*)(lua_State*)' for argument '1' to 'void luabind::set_pcall_callback(int (*)(lua_State*))'|

因此,似乎错误是函数需要常规函数指针,而不是类成员函数指针.有没有办法强制转换或使用中间函数指针传递给set_pcall_callback()函数?

So it seems that the error is that the function expects a regular function pointer, not a class member function pointer. Is there a way to cast or use an intermediate function pointer to pass to the set_pcall_callback() function?

谢谢!

推荐答案

否. 成员函数不是自由函数.类型完全不同,成员函数(PTMF)的指针与函数指针是完全不同的,不兼容的对象. (例如,PTMF通常要大得多.)最重要的是,必须始终将指向成员的指针与指向要调用其成员的对象的实例指针一起使用,因此您甚至不能 use PTMF与使用函数指针的方式相同.

No. A member function is not a free function. The type is entirely different, and a pointer to a member function (PTMF) is a completely different, incompatible object from a function pointer. (A PTMF is usually much bigger, for example.) Most importantly a pointer-to-member must always be used together with an instance pointer to the object whose member you want to call, so you cannot even use a PTMF the same way you use a function pointer.

与C代码进行交互的最简单解决方案是编写一个全局包装函数来分派您的调用,或者使您的成员函数 static (在这种情况下,它实质上成为一个自由函数):

The easiest solution for interacting with C code is to write a global wrapper function that dispatches your call, or to make your member function static (in which case it becomes essentially a free function):

// global!

Engine * myEngine;
int theCallback(lua_State * L)
{
  return myEngine->pcall_log(L);
}

Engine::Run()
{
  /* ... */
  myEngine = this;
  luabind::set_pcall_callback(&theCallback);
  /* ... */
}

这里的概念性问题是您拥有引擎 class ,尽管实际上只有一个实例.对于具有许多对象的真正类,PTMF毫无意义,因为您必须指定用于调用的对象,而您的引擎类实际上可能是单例类,它可能是完全静态的(即美化的命名空间) ).

The conceptual problem here is that you have an engine class, although you will practically only have one single instance of it. For a genuine class with many objects, a PTMF wouldn't make sense because you'd have to specify which object to use for the call, whereas your engine class perhaps is essentially a singleton class which could be entirely static (i.e. a glorified namespace).

这篇关于C ++类成员函数指针到函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆