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

echo("備忘録");

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

C#でCOMを使ってみた。その3

何か、前回から随分間が空いてしまいました。
実家に帰ってたり、仕事のことで悩んでたりで、色々ありまして…すいません。

さて、DirectSoundの件ですが、とりあえず一通りネイティブなDirectXを使用したコードも完成して、コンパイルも通った。
あとは実行&デバッグだと思い、デバッグ実行させたら、こんな実行時エラーが。

failed: System.InvalidCastException : 型 'idirectSoundCaptureBuffer8' の COM オブジェクトをインターフェイス型 'IDirectSoundCaptureBuffer8' にキャストできません。
IID '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}' が指定されたインターフェイスのCOM コンポーネント上での QueryInterface 呼び出しのときに次のエラーが発生したため、この操作に失敗しました: インターフェイスがサポートされていません
(HRESULT からの例外: 0x80004002 (E_NOINTERFACE))。

キャスト出来ない?
ていうか、インスタンス作成&キャスト自体はこれよりだいぶ前の処理で、問題なく成功しているのに…

とりあえず、

  • 念のためインスタンス作成&キャスト箇所のIID間違いやポインタ確保&解放をチェックしたけど、全く問題なし。
  • レジストリのあるキーの値が壊れているとそういうエラーが発生するらしいけど、それも問題なし。
  • メソッドに[STAThread]属性をつけると直る事があるらしいけど、特に変化なし。(ただ、結果的にはこれに関連する事項だったんですが。)

で、ちょっとハマっていたんですが、下記ブログにそのものズバリの答えが書いてありました。感謝感激です!
architect360.apricot-jp.com

なるほど、要は「COMオブジェクトは(例えクラスメンバ変数などにしたとしても)作成したスレッドとは別のスレッドでそのまま使用することは出来ない」ということですね。
僕のプログラムでは、COMオブジェクトのインスタンスをメインスレッドで作成して、それを別スレッドの音声キャプチャ処理でそのまま使用していたのですが、それが原因だったようです。

なので、音声キャプチャ処理のスレッド内でキャプチャ開始直前にCOMオブジェクトを作成するように変更したら、このエラーは出なくなりました。

まあ、この後も色々あるんですけどね。それはまた後日。


しかし、仕事…というか会社、どうしようなあ。さっさと行動すべきかなあ。
もちろん、ITエンジニア自体を辞めるつもりなんて、さらさらありませんけどね。