stdcall_thunk
昨日のクラス名が長すぎる問題ですが、早速
direct_sound_buffer → direct_sound_sink
direct_sound_capture_buffer → direct_sound_source
に変更しました。
これで、vc8ideディレクトリ配下以外は、inspectに引っかからなくなりました。
vc8ideディレクトリにはWin32 GUI Genericsを使ったサンプルが入っているのですが、この際フルスクラッチのコードと置き換えようかと思います。
Win32でGUIのフレームワークを使わずに済ます場合、どうしても__stdcall呼び出し用のthunkが欲しくなります。
そこで、以前作成したcdecl_thunkと同じインタフェースでstdcall_thunkも作ってみました。
<hamigaki/detail/i386/stdcall_thunk.hpp>
__cdeclの場合は、引数をスタックに積み直していましたが、__stdcallの場合は関数側でスタックの後始末をしてくれるので、スタックのトップを書き換えてjmpするだけで済みます。
以下、サンプルコードです。
#include <hamigaki/detail/stdcall_thunk.hpp> #include <hamigaki/detail/virtual_memory.hpp> #include <iostream> class hoge { public: void foo(long a, long b) { std::cout << "this=" << static_cast<void*>(this) << ", a=" << a << ", b=" << b << std::endl; } static void stdcall_helper(hoge* this_ptr, long a, long b) { this_ptr->foo(a, b); } }; typedef void (*func_type)(long, long); int main() { hoge h; h.foo(1,2); // 通常の呼び出し // 仮想メモリの準備 using namespace hamigaki::detail; virtual_memory buffer(sizeof(stdcall_thunk)); stdcall_thunk* thunk_ptr = static_cast<stdcall_thunk*>(buffer.address()); // アドレスの設定 thunk_ptr->set_instance(func_ptr_cast<void*>(&hoge::stdcall_helper), &h); // 命令キャッシュのクリアとメモリ保護設定 buffer.flush_icache(); buffer.protect(virtual_memory::execute|virtual_memory::read); func_type func_ptr; thunk_ptr->copy_address(func_ptr); (*func_ptr)(1,2); // サンク経由の呼び出し }