LoginSignup
1
1

More than 5 years have passed since last update.

[D言語] Derelict3のGLFWでglfwSet(Key|Char|CursorEnter)Callbackで勝手にハマった

Last updated at Posted at 2014-04-02

まず、Derelictとはなにか

OpenGLとかGLFW,SDL,OpenALかのD言語向けバインディングライブラリのこと

免責事項

α改はD言語を学習中でありまだ良くわかってないので以下のことが間違ってるかもしれません・・・

ご了承ください

間違っていた場合は指摘してくださると幸いです

使い方

当たり前だけど、D言語のコンパイラ(dmdとかldcとかが入りますので入れておいてください)

まず

zsh
% git clone https://github.com/aldacron/Derelict3
% cd Derelict3/build
% dmd build.d
% ./build

これでDerelict3/lib/使っているDコンパイラ(dmd/ldcとか)に*.a(Windowsならlib)と出力されます

そして

作業ディレクトリを作ってそこにlibというディレクトリを作りそこにすべての.aを移動して

Derelict3/import/derelictを作業ディレクトリに設置(別にコンパイラの参照するパスにおいても構いませんけど)

これでOk

とりあえず、使ってみる

って書こうと思ったけどすでにQiitaに投稿されてる方がいたのでそちらへのリンクを貼ります

D言語によるマルチプラットフォームなゲームライブラリバインダ Derelict3の使い方

で、今回どこでハマったか

まず、Callbackを書いて登録しようとしました

実際のコードはこんな感じ

mixin template Callbacks(){
  void keyCallbackFunction(GLFWwindow* window, int key, int scancode, int action, int mods){
    // コード
  }
}
class TestGl{
  mixin Callbacks;
  static GLFWwindow* window;

  this(){
    // loadとか初期化とか
    glfwSetKeyCallback(window, cast(GLFWwindow)&keyCallbackFunction);
  }
}

こんな感じで色々試行錯誤したんですけど 関数リテラル(functionへのポインタ)渡すところ(というかキャスト)がコンパイルエラー吐かれたり(上の例だとどうなるか忘れてしまいましたが・・・)

とりあえず、試した結果をリストにすると

  • キャストのとことかでコンパイルエラー
  • なんとかエラー回避してコンパイル通してもコールバックが呼ばれるようなことするとCoreDump

とかこうなります

[追記:2014/04/03]  
repeatedly氏のコメントにより僕の間違いがわかりました  
詳しくは下のコメントを見てください  
簡潔に説明しますと、Callbackというclassのメンバ関数はdelegateとして扱われるそうです
ですからメンバ関数である`keyCallbackFunction`はdelegateとして扱われていたためfunctionが要求されている場面では使えなかったというわけです  
下に解決したコードを書きます  

解決方法

で、解決方法はですね

ズバリ直接書いちゃえば解決しましたはい

実際のコードがこちら

class TestGl{
  static GLFWwindow* window;

  this(){
    glfwSetKeyCallback(window, cast(GLFWkeyfun)
        function void (GLFWwindow* window, int key, int scancode, int action, int mods){
          // コード
        });
  }
}

うん、これならちゃんと行くんですよね

直接書くという方法も行けます

追記:2014/04/03

それから、delegateをstatic修飾子によりfunctionとすることにより、mixin templateを用いて使うことができるようになります

mixin template Callbacks(){
  static void keyCallbackFunction(GLFWwindow* window, int key, int scancode, int action, int mods){
    // コード
  };
}
class TestGl{
  mixin Callbacks;
  static GLFWwindow* window;

  this(){
    // loadとか初期化とか
    glfwSetKeyCallback(window, cast(GLFWwindow)&keyCallbackFunction);
  }
}

こうやったほうがスマートですね(?)

とりあえず、僕的にはcallbackは別のクラスとして扱いたかったので、mixin template Callback()としました

とりあえず、結論は

static修飾子をつければスマートに解決する

はいこんな感じで今回は以上です〜

α改

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1