アプリケーションで GRF ファイルから Directshow IFilterGraphs をロードすると、DLL にグローバルに登録されている通常のフィルターに対して正常に機能します。
// open structured storage file...
hr = pStorage->OpenStream(L"ActiveMovieGraph", 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
if (SUCCEEDED(hr)) {
hr = pPersistStream->Load(pStream);
pStream->Release();
}
ただし、一部のフィルターは、IClassFactory 実装から呼び出される CoRegisterObject を使用して EXE にローカルに登録されます。これらのフィルターは、IClassFactory 実装が IClassFactory::CreateInstance 呼び出しを受け取ると、C++ new で作成されます。
HRESULT hr = CoRegisterClassObject(*m_pTemplate->m_ClsID, this, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &m_RegisterKey);
ローカル フィルターは、CoCreateInstance を介して直接作成された場合に正常に機能します。C++ new で直接作成した場合も問題なく動作します。
CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&instance);
これらのローカル フィルターを含む GRF ファイルの読み込みは機能せず、HRESULT 0x80040154 Class not registered from IPersistStream::Load を返します。
アプリケーションの IClassFactory::CreateInstance 関数は呼び出されませんが、CoCreateInstance API は IPersistStream::Load 中に正しい CLSID で呼び出されますが、IPersistStream::Load 呼び出しとは別のスレッドから呼び出されます (COM アパートメント スレッドで初期化されたメイン アプリケーション スレッド上)。 )。もう 1 つの違いは、IPersistStream::Load から呼び出されたときの dwContext が CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER であることです。ただし、メイン スレッドからの CoCreateInstance 呼び出しは、この dwContext 値で引き続き機能します。CLSCTX_INPROC_HANDLER フラグを含む CoRegisterClassObject 呼び出しは、E_INVALIDARG で失敗します。
ole32.dll!CoCreateInstance(const _GUID & rclsid, IUnknown * pUnkOuter, unsigned long dwContext, const _GUID & riid, void * * ppv) Line 96 C++
quartz.dll!_CoCreateFilter@8() + 0x1a bytes
quartz.dll!CFilterGraph::OnCreateFilter() + 0x55 bytes
quartz.dll!CFGControl::CGraphWindow::OnReceiveMessage() + 0x2d05 bytes
quartz.dll!WndProc() + 0x3e bytes
user32.dll!_InternalCallWinProc@20() + 0x23 bytes
user32.dll!_UserCallWinProcCheckWow@32() + 0xb7 bytes
user32.dll!_DispatchMessageWorker@8() + 0xed bytes
user32.dll!_DispatchMessageW@4() + 0xf bytes
quartz.dll!ObjectThread() + 0x65 bytes
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
rclsid {CA6B3460-28B3-4A6E-A7FC-A83CF1DEEC49} const _GUID &
pUnkOuter 0x00000000 IUnknown *
dwContext 3 unsigned long
riid {IID_IBaseFilter} const _GUID &
アプリケーションは、MFC アプリケーションの推奨事項として CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) を呼び出します。CoRegisterClassObject の呼び出しで異なるコンテキストとフラグの値を使用しようとしましたが、成功しませんでした。GRF ファイルには、プロセス ローカル フィルターの正しい CLSID が確実に含まれています。
この動作は、アプリケーションの Win32 および x64 ビルドと同じです。ホスト OS は Windows 7 x64 です。
IFilterGraph シリアル化は、CoRegisterClassObject に登録されたプロセス ローカル フィルターをサポートしていますか? もしそうなら、アプリケーションの動作に問題がありますか? この問題をさらに診断するために実行できる手順はありますか?