我正在尝试在 CLR C++ 中编写 GMFBridge 和 DirectShow。我正在尝试将其性能与同一解决方案中的 GMFBridgeLib 和 DirectShowLib 进行比较,看看哪个更有效。
现在我正在关注 GMFBridge 源代码来设置 C++ 捕获。我遇到的一个问题是需要全局的对象,以便可以通过 GUI 按钮访问它们。GMFBridge 代码如下:
private:
IGMFBridgeControllerPtr m_pBridge;
然后在设置代码中使用如下:
HRESULT hr = m_pBridge.CreateInstance(__uuidof(GMFBridgeController));
if (FAILED(hr))
{
return hr;
}
// init to video-only, in discard mode (ie when source graph
// is running but not connected, buffers are discarded at the bridge)
hr = m_pBridge->AddStream(true, eMuxInputs, true);
我当前的问题是 CLR 声明任何全局都必须是某种形式的指针,* 或 ^ 取决于托管或非托管。它不会让我像 GMFBridge 源代码那样添加全局变量。如果我创建一个指针:
IGMFBridgeControllerPtr* pBridge2;
并尝试在我的 GUI 代码中使用它:
(*pBridge2).CreateInstance(__uuidof(GMFBridgeController));
(*pBridge2).AddStream(true, eMuxInputs, true);
它确实可以编译,但是当我运行它时,代码会崩溃
An unhandled exception of type 'System.NullReferenceException' occurred in Program.exe.
Addidional information: Object reference not set to an instance of an object.
在代码块上
void _Release() throw()
{
if (m_pInterface != NULL) { <--------------
m_pInterface->Release();
}
}
在 comip.h 第 823 行中调用:
HRESULT CreateInstance(const CLSID& rclsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
{
HRESULT hr;
_Release();
if (dwClsContext & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)) { <----------
IUnknown* pIUnknown;
hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));
if (SUCCEEDED(hr)) {
hr = OleRun(pIUnknown);
if (SUCCEEDED(hr)) {
hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
}
pIUnknown->Release();
}
}
else {
hr = CoCreateInstance(rclsid, pOuter, dwClsContext, GetIID(), reinterpret_cast<void**>(&m_pInterface));
}
if (FAILED(hr)) {
// just in case refcount = 0 and dtor gets called
m_pInterface = NULL;
}
return hr;
}
从这行代码调用的 comip.h 第 626 行
(*pBridge2).CreateInstance(__uuidof(GMFBridgeController));
唯一可行的方法是创建一个不是点对象的局部变量,但是我无法将其设置为全局变量,或者在 GUI 对象中使用它。
如果我将其设为本地:
IGMFBridgeControllerPtr pBridge;
pBridge.CreateInstance(__uuidof(GMFBridgeController));
这样可行。