![](/img/trans.png)
[英]How to implement COM callback interface in C++, from C# assembly, using `#import` and `tlb` file?
[英]Using a C++ callback interface in C#
我正在編寫一個需要使用DirectShow錄制視頻的應用程序-為此,我正在使用Interop庫DirectShowLib,它看起來很棒。
但是,由於樣本已寫入文件中,因此現在我需要獲取回調通知,因此可以添加數據單元擴展。 根據msdn文檔,在C ++中,這是通過實現IAMWMBufferPassCallback接口並將結果對象傳遞到引腳的IAMWMBufferPass接口的SetNotify方法來完成的。
因此,我創建了一個小類,該類從DirectShowLib實現IAMWMBufferPassCallback接口:
class IAMWMBufferPassCallbackImpl : IAMWMBufferPassCallback
{
private RecordingPlayer player;
public IAMWMBufferPassCallbackImpl(RecordingPlayer player)
{
this.player = player;
}
public int Notify(INSSBuffer3 pNSSBuffer3, IPin pPin, long prtStart, long prtEnd)
{
if (player.bufferPin == pPin && !player.firstBufferHandled)
{
player.firstBufferHandled = true;
//do stuff with the buffer....
}
return 0;
}
}
然后,我檢索了所需引腳的IAMWMBufferPass接口,並將該類的實例傳遞給SetNotify方法:
bufferPassCallbackInterface = new IAMWMBufferPassCallbackImpl(this);
IAMWMBufferPass bPass = (IAMWMBufferPass)DSHelper.GetPin(pWMASFWriter, "Video Input 01");
hr = bPass.SetNotify(bufferPassCallbackInterface);
DsError.ThrowExceptionForHR(hr);
沒有引發異常,表明SetNotify方法成功。
現在的問題是,我的回調對象中的Notify方法永遠不會被調用。 該視頻記錄沒有問題,只是回調根本沒有執行。
我做互操作的方式有問題嗎?
您進行互操作的方式看起來很好。 我看了看MSDN文檔,看起來您也朝着正確的方向前進,所以我不知道為什么它不進行回調。
但是,一旦完成回調,您可能需要確保調用Marshal.ReleaseComObject(pNSSBuffer3)。 有時,直到所有其他引用都被刪除后,樣本緩沖區才會釋放出來進行處理。 SampleGrabber就是這種情況,因此可能與此相同。
您可能應該使用委托:
delegate int NotifyDelegate(INSSBuffer3 pNSSBuffer3, IPin pPin, long prtStart, long prtEnd);
void run(){
bufferPassCallbackInterface = new IAMWMBufferPassCallbackImpl(this);
IAMWMBufferPass bPass = (IAMWMBufferPass)DSHelper.GetPin(pWMASFWriter, "Video Input 01");
NotifyDelegate d = new NotifyDelegate(bufferPassCallbackInterface.Notify);
hr = bPass.SetNotify(d);
DsError.ThrowExceptionForHR(hr);
}
但是,我不太確定如何在托管類上實現非托管接口。 C ++中的INSSBuffer3 *與C#中的新INNSBuffer3()不直接相關。
為了回應您的評論,SetNotify函數定義為
HRESULT SetNotify(
[in] IAMWMBufferPassCallback *pCallback
);
因此,它需要一個指向IAMWMBufferPassCallback的實現的指針。
MSDN說pCallback是pCallback a
指向應用程序的IAMWMBufferPassCallback接口的指針。
委托是(試圖成為)托管的等效於IAMWMBufferPassCallback的指針。 回調通常是一種方法,而不是對象。 因此,傳遞委托的實例將為您工作。 另一個類似的示例是InternetSetStatusCallback ,您可以在其中傳遞指向InternetStatusCallback的實現的指針。
我會嘗試一下,如果它不起作用,為什么不嘗試一個已經有人完成所有辛苦工作的圖書館呢? DirectShowNet可能是一個選項(我從未使用過)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.