今までManaged DirectXを扱ってきたけど、訳あってUnmanagedなコードも扱う必要が出てきた。
で、キャプチャデバイスの列挙のため「DirectSoundCaptureEnumerate」関数をコールする必要があったのだけど、MSDN見たら、
HRESULT WINAPI DirectSoundCaptureEnumerate(
LPDSENUMCALLBACK lpDSEnumCallback,
LPVOID lpContext
);
pDSEnumCallback
DSEnumCallback 関数のアドレス。この関数は、システムにインストールされている各 DirectSoundCapture オブジェクトに対して呼び出される。pContext
ユーザー定義コンテキストのアドレス。列挙コールバック関数が呼び出されるたびに、このコンテキストが関数に渡される。
で、コールバック関数ってどう設定するの?
って事で調べたのでメモ。
と言っても、特別難しいわけではなかった。
…ていうか、MSDNにズバリそのまま書いてあった。
https://msdn.microsoft.com/ja-jp/library/843s5s5x(v=vs.110).aspx
まあざっくりと言ってしまえば、
手順1.デリゲートを宣言する
手順2.そのデリゲート型の変数を使用箇所で作成し
手順3.実際のコールバック関数の中身を作成し
手順4.コールバック関数(のポインタなど)を引数として必要とする関数(今回はDirectSoundCaptureEnumerate)に手順2で作成した変数を引数として渡す。
でOK。
コード:
using System; using System.Runtime.InteropServices; // これがデリゲート型宣言で必要 // using Microsoft.DirectX; // using Microsoft.DirectX.DirectSound; namespace Sample { public unsafe class SampleClass { [DllImport("dsound.dll")] private extern static int DirectSoundCaptureEnumerate(DSEnumCallback cb, void* lpContext); private delegate bool DSEnumCallback(Guid* guid, string desc, string module, void* lpContext); // 手順1 public SampleClass() { DSEnumCallback myCallBack = new DSEnumCallback(SampleClass.deviceEnum); // 手順2 int retVal = DirectSoundCaptureEnumerate(myCallBack, (void*)0); // 手順4 } // DSEnumCallback関数は、デバイス列挙を続けるならtrue、終了するならfalseを返す。 private static bool deviceEnum(Guid* guid, string desc, string module, void* lpContext) // 手順3 { if (null != guid) { return false; } return true; } }
…ていうか、やはりポインタやら何やら、嫌な言葉がいっぱい出てくるようになった。
これも、C++から逃げ続けてきたツケ、なのかも。