読者です 読者をやめる 読者になる 読者になる

echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

C#でCOMを使ってみた。

.net Windows

ここにも少し書いたんですが、結局ネイティブなDirectXC#からうんたらかんたらする必要があったので、備忘録がてらメモ。

さて、DirextXはCOMという事ですが、C#でCOMを使う場合、以下の手順が必要です。

COM定義の変換

COMオブジェクトをC#で使用する方法の一つに「COM定義の変換」がありますが、これは「コクラス」を作成することで対応できます。
コクラスの作成は、例えばDirectXの「DirectSoundCapture8」を使用する場合、

[Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx")]
[ComImport]
private class DirectSoundCapture8Class
{
}

というように、[ComImport]や[Guid]属性を記載したクラスを作成すればOK。(Guidの値は、ヘッダーファイル(今回はdsound.h)などから調べる必要があります。)

COMインターフェースの変換

で、COMインターフェースはというと、例えばIDirectSoundCapture8インターフェースの場合、

[Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IDirectSoundCapture8
{
    [PreserveSig]
    int CreateCaptureBuffer(ref DSCBUFFERDESC pcDSCBufferDesc, out IntPtr ppDSCBuffer, [MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter);
    [PreserveSig]
    int GetCaps(ref DSCCAPS pDSCCaps);
    [PreserveSig]
    int Initialize(ref Guid pcGuidDevice);
}

のように、[Guid]や[InterfaceType]属性を指定したインターフェースを作成すればOK。

あと、これらのメソッドがエラーとなる値を返した場合、デフォルト設定では例外(System.COMException)が発生するので(例外のエラーコードで結果が分かる)、それを回避する場合は[PreserveSig]属性を付けてメソッドの戻り値としてエラーコードを受け取るようにします。

なお

  • メソッドは「IUnknown」及び「IDispatch」メンバ以外の全てのメソッドを定義しなければならない。
  • メソッドの記載順は必ずヘッダファイルと同じ順番でなければならない(MSDNなどの記載順とは異なる)

ので注意。



…すいません。ちょっと時間がないので、続きはまた後日に。


【追記】
今日、VS起動中にPCがフリーズしたので再起動したら、メインの.csファイルが真っ白に…
ていうか、何とかならないのかな、これ。VSの自動バックアップって、保存した瞬間にバックアップがなくなるから、保存後にフリーズするとどうしようもないし。

…やはり、こまめにバックアップとるしか無いのか?というより、そんなに頻繁にフリーズするPCが問題?