5

lua to C++ ラッパーとして luabind を使用しています。Luabind は、独自のコールバック関数を使用して lua によってスローされた例外を処理する方法、set_pcall_callback() を提供します。そこで、ドキュメントの例を言い換えました。変更は logger->log() 関数であり、関数を「Engine」というクラスに配置したため、通常のグローバル関数ではなく、メンバー関数になりました。私の問題があるようです。

関連するコードスニップは次のとおりです。

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;
}

コンパイル中にコンパイラが言うことは次のとおりです。

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() 関数に渡す方法はありますか?

ありがとうございました!

4

4 に答える 4

14

いいえ。メンバー関数はフリー関数ではありません。型はまったく異なり、メンバー関数 (PTMF) へのポインターは、関数ポインターとはまったく異なる、互換性のないオブジェクトです。(たとえば、PTMF は通常、はるかに大きくなります。)最も重要なことは、メンバーへのポインターは、呼び出したいメンバーを持つオブジェクトへのインスタンス ポインターと常に一緒に使用する必要があるため、PTMF を同じ方法で使用することさえできません。関数ポインタを使用します。

C コードと対話するための最も簡単な解決策は、呼び出しをディスパッチするグローバル ラッパー関数を作成するか、メンバー関数を静的にすることです(この場合、実質的にフリー関数になります)。

// global!

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

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

ここでの概念的な問題は、エンジンクラスがあるということですが、実際にはそのインスタンスは 1 つしかありません。多くのオブジェクトを持つ本物のクラスの場合、呼び出しに使用するオブジェクトを指定する必要があるため、PTMF は意味がありませんが、エンジン クラスはおそらく本質的に完全に静的なシングルトン クラスです (つまり、栄光化された名前空間)。 )。

于 2011-08-02T07:33:16.050 に答える
0

コールバックとして、通常はstatic functions:を使用します。

class Engine //Whole class not shown for brevity
{
    ....
    static int pcall_log(lua_State*);
    ...
}

これで問題が解決します。

于 2011-08-02T07:34:14.813 に答える