0

私はCOMについてほとんど知りません、そしてGoogleでCOMを検索してもCOMはまったく見つかりませんでした(おそらく代わりに.comアドレスを検索したためです)。

ビデオキャプチャハードウェアを使用しています。そのSDKを使用すると、フレームがキャプチャされたときにコールバックを登録できます。オブジェクトインターフェイスはそのコールバックにパラメータとして渡され、そのオブジェクトにクエリを実行することで、(キャプチャされたフレームピクセルへの)大きなバッファアドレスやその他の情報を取得できます。

さて、Release()を呼び出すと、実際にはメモリが削除されないように見えますが、参照カウントが減少し、カウントが0に達すると、削除されますよね?では、上記の大きなバッファアドレスについては、「delete」キーワードを使用してバッファを「削除」するのはどうでしょうか。

私たちのプログラム(私が書いたものではなく、プログラムを書いた人が会社を辞めた)は、バッファーへのポインターをあるクラスにコピーしますが、コールバックでRelease()を呼び出すことはないようです。後で、バッファはクラスで「削除」されます。フレームインターフェイスオブジェクトをRelease()すると、バッファも削除されるようです。しかし、それらは同じですか?

COMはどういうわけか参照をカウントしますが、ユーザーのコードがそのメモリを削除した場合はどうなりますか?質問がわかりにくい場合は申し訳ありません。つまり、COMオブジェクトから取得したバッファを削除しても安全ですか。

簡略化されたコード:疑わしい状況

void mycallback(IFrame f)
{
  char* buffer;
  f->GetBuffer(buffer);
  MyClass m(buffer);
  ...
}

MyClass::DeleteBuffer()
{
  delete m_buffer;
}
4

3 に答える 3

2

コードがフレームバッファの内容を独自のバッファにコピーするとき、特別なことは何も起こりませんでした。フレームバッファは引き続きCOMコードによって所有され、コード自体のバッファは引き続きそのコードによって所有されます。COMバッファを削除しないでください。COMコードがバッファを削除すると、未定義の動作が発生します。最初にAddRef()を呼び出した場合にのみ、COMインターフェイスポインタでRelease()を呼び出す必要があります。このようなシナリオでは、コールバックを呼び出す前に、COMコードによってAddRef()呼び出しが行われました。そして、Release()呼び出しは、コールバックが戻った後に行われます。

フレームがコールバックでコピーされるのを見るのはごく普通のことであり、フレームバッファは通常、コールバックの期間中のみ有効なままです。したがって、後で使用する場合はコピーする必要があります。

メモリリークを追跡している場合、これが原因ではない可能性があります。フレームバッファに参照カウントの問題があった場合、プログラムは使用可能なすべてのメモリを消費する前に1分以上持続できませんでした。

于 2012-10-31T08:51:51.430 に答える
0

この場所演算子delete、CoTaskMemFreeを使用してみてください

于 2012-10-31T08:49:06.120 に答える
0

COMインターフェースの扱いはもっと難しいです:-)

  1. IUnknown :: AddRef()とIUnknown :: Release()の呼び出しが一致していることを確認してください
  2. 同じコンテキストにいる限り、COMインターフェイスからバッファを取得した場合でも、バッファを明示的に削除できます。ただし、削除後にポインタを無効にして、後処理の問題が発生しないようにしてください。

    MyClass :: DeleteBuffer(){if(m_buffer){delete m_buffer; m_buffer = null; }}

于 2013-03-12T08:35:13.430 に答える