我正在構建基於VideoRendererElement項目(http://videorendererelement.codeplex.com/)的webcam應用程序,該項目使用DirectShowLib和Interop與非託管activex組件。我使用的是Visual Studio 2010,但是面向.NET 3.5(2.0 clr運行時)。調用託管代碼的非託管代碼適用於開發機器,不適用於部署機器
我已經能夠在我的開發機器上構建和運行應用程序,沒有任何問題(甚至是Visual Studio之外)。但是,當我在目標機器上部署應用程序時(Windows 7,.NET爲最新版本,C++可再發行版本爲最新版本),應用程序將崩潰。我設置了一個額外的方法,將正在運行的應用程序記錄到目標機器上的文本文件中,追溯一個關鍵區別,非託管代碼調用託管代碼中的方法,僅缺少以前定義的靜態字段。這隻發生在目標機器上(我部署代碼的機器)。以下是一些代碼片段和我登錄的內容。令人困惑的是,這個錯誤只發生在目標機器上。任何幫助指引我在正確的方向將不勝感激。
namespace MediaBridge
{
.....
public class MediaBridgeManager
{
public delegate void NewMediaGraphInfo(MediaBridgeGraphInfo GraphInfo);
private static readonly Dictionary<string, NewMediaGraphInfo> _delegateHash = new Dictionary<string, NewMediaGraphInfo>();
......
public static void AddMediaGraphInfo(MediaBridgeGraphInfo GraphInfo)
{
if (_delegateHash.ContainsKey(GraphInfo.MediaUrl))
{
NewMediaGraphInfo callback = _delegateHash[GraphInfo.MediaUrl];
_delegateHash.Remove(GraphInfo.MediaUrl);
/* Suppress all errors on the callback */
try
{
callback(GraphInfo);
}
catch {}
}
}
......
public static bool RegisterCallback(string MediaUrl, NewMediaGraphInfo Callback)
{
bool returnval = true;
MediaUrl = FormatUrl(MediaUrl);
if (!_delegateHash.ContainsKey(MediaUrl))
{
_delegateHash.Add(MediaUrl, Callback);
}
else
{
returnval = false;
}
return returnval;
}
}
}
應用程序的.NET部分之前調用RegisterCallback()第一,用URL和回調函數填充_delegateHash。這在目標機器上的日誌文件中得到驗證。
現在的非託管部分:
STDMETHODIMP CMediaBridgeSourceFilter::Load(LPCOLESTR lpwszFileName, const AM_MEDIA_TYPE *pmt)
{
/* Thread-saftey */
CAutoLock cAutoLockShared(&m_cSharedState);
HRESULT phr = S_OK;
/* Create the output pin for our filter */
m_pPin = new CMediaBridgeSourceFilterPin(&phr, this);
/* Create a new class to store information about us/graph in it */
MediaBridge::MediaBridgeGraphInfo^graphInfo = gcnew MediaBridge::MediaBridgeGraphInfo();
/* Set the media url sent */
graphInfo->MediaUrl = gcnew System::String(lpwszFileName);
/* Set the pointer to the filter graph */
graphInfo->FilterGraph = System::IntPtr(this->GetFilterGraph());
/* Store the pointer for our instance of the filter */
graphInfo->SourceFilter = System::IntPtr(this);
/* Do the callback into our managed code */
MediaBridge::MediaBridgeManager::AddMediaGraphInfo(graphInfo);
return phr;
}
根據我的日誌文件媒體橋:: MediaBridgeManager :: AddMediaGraphInfo()被調用基於.NET的一面,但回調永遠達不到,因爲_delegateHash變量現在空了。
這裏是我的日誌文件說我試圖部署的應用程序在目標機器上:
RegisterCallback(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ Contains Key: True Delegate Hash count: 1
InitializeDirectShow(): RegisterCallback == true, Url == DShowMediaBridge://d0ffd222-d023-483b-8fc7-4b4035ce3922
AddMediaGraphInfo(): MediaUrl = dshowmediabridge://d0ffd222-d023-483b-8fc7-4b4035ce3922/ FilterGraph: 71122304 Contains Key: False Delegate Hash count: 0
注意委派哈希計數(_delegateHash.Count)現在怎麼是在0時非託管代碼調用AddMediaGraphInfo()。
有沒有什麼我應該做的,以確定目標機器上的VS的COM/C++的DLL,我在開發機器上爲我做的?
你是否在調試模式下編譯?你可能會遇到VS調試模式redist dll的DLL問題,它只能在裝有VS的PC上安裝。嘗試釋放... –
謝謝J.N.我已經在發佈模式下構建瞭解決方案。 – Reg
儘管我仍然不能100%確定它爲什麼在開發框中工作,但由於這是一個從Visual Studio 2005/2008構建的開放源代碼解決方案,我將其導入到VS 2010中,我試圖將原始ActiveX控件文件複製到應用程序的目錄覆蓋用解決方案構建的VS2010,重新註冊它,現在它可以工作。我認爲這與VS 2010構建它的Windows SDK(7.1)或更高版本的MSBuild針對.NET 4有關,我知道.NET 4如何處理與COM的互操作。 – Reg