LoginSignup
0
0

More than 1 year has passed since last update.

SDL_CreateThreadでラムダ式・クラスメンバを呼び出し

Posted at

内容

 SDLはC言語ベースのライブラリであり、C++のモダンな諸機能には対応していません。そんな中で、ラムダ式やクラスのメンバ関数を用いる方法についての備忘録です。

まずはSDL_Threadの定義

 SDL_Threadのスレッド生成関数は以下のように定義されています。

SDL_Thread* SDL_CreateThread(SDL_ThreadFunction fn,
                             const char* name,
                             void* data)

 この引数について、Wikiではfnはスレッドで実行する関数、nameはスレッド名、dataは関数fnに渡す引数であると説明されています。( https://wiki.libsdl.org/SDL_CreateThread
 また、SDL_thread.hでは、第一引数の型SDL_ThreadFunctionは、

typedef int (SDLCALL * SDL_ThreadFunction) (void *data);

として定義されています。( https://www.libsdl.org/tmp/SDL/include/SDL_thread.h
 なお、ここで出てきているSDLCALLは、__cdecl_SystemとしてDEFINEマクロで定義されている値です。
 つまり、void*を引数に取りintを返す関数のポインタであれば、SDL_CreateThreadの第一引数として渡すことが可能になります。

ラムダ式の扱い方

 キャプチャリストが空であるラムダ式は、引数と返り値の型が同じ関数ポインタに暗黙的に変換することが可能です。( https://riptutorial.com/ja/cplusplus/example/1970/関数ポインタへの変換
 そのため、キャプチャリストが空ならば、単にvoid*を引数に取りintを返すようにさえすれば、ラムダ式はそのまま渡すことが可能ということになります。キャプチャリストは使えませんが、SDL_CreateThreadの第三引数で引数を渡すことができるので、それによって困ることはあまりないでしょう。
 万一、どうしても必要になった場合は、ラムダ式を実行するコールバック関数を別に定義して使ってください。(参考:https://qiita.com/studiork/items/2d2951542d79cf94fb84

メンバ関数の扱い方

 皆さんご存知の通り、メンバ関数ポインタは普通の関数ポインタとは別物になるので、ラムダ式の場合と違って、そのまま渡すというわけには行きません。オブジェクトの情報を別で引数として受け取って、引数の情報を使ってコールバック関数内で呼び出すというワンクッションが必要になります。

class Foo{
public:
    int do_something();
}

Foo obj;

SDL_CreateThread([](void *arg)->int{
    Foo *p_obj=reinterpret_cast<Foo*>(arg);
    return p_obj->do_something();
    //return 0; //do_something()の戻り値がintでないとき
}, "ThreadName", &obj);

 多くの箇所で同様の処理を行う場合は、すべての場所でラムダ式を書くのは煩雑なので、同様の処理をテンプレート関数で書いて使う方が楽かもしれません。下の参考サイトは、そちらのアプローチをとっているので、必要に応じて参考にしてください。
(参考:https://kazuhooku.hatenadiary.org/entry/20110126/1296031454

あとがき

 この記事は古い下書きをそのまま公開しています。不足点等ある可能性がありますので、周辺情報の確認の上でご利用ください。また、もしも誤りや説明不足な点などありましたら、ぜひコメント頂ければと思います。

0
0
0

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
0
0