我有以下使用Visual Studio 2015编写并使用Windows SDK 7.1的测试设置:
在Debug中进行编译并运行测试应用程序时,该功能似乎正常工作,并且事件已按预期方式处理。 问题是,应用程序在退出时崩溃,到目前为止,我仍无法弄清原因。非常感谢任何人的帮助。
现在了解详细信息: 应用程序如下所示:
#include <windows.h>
#include <initguid.h>
#include <atlbase.h>
#include <streams.h>
// {E705C8D3-EE60-4012-9E83-3CFE4A11D1B5}
DEFINE_GUID(CLSID_TestFilter,
0xe705c8d3, 0xee60, 0x4012, 0x9e, 0x83, 0x3c, 0xfe, 0x4a, 0x11, 0xd1, 0xb5);
void Test()
{
CComPtr<IBaseFilter> pFilter;
HRESULT hr = CoCreateInstance(CLSID_TestFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pFilter);
if (FAILED(hr))
return;
}
void main()
{
CoInitialize(NULL);
Test();
CoUninitialize();
}
当退出main函数的作用域时会发生崩溃,而我从调用堆栈中什么也没得到。
CS测试定义了以下接口
using System;
using System.Runtime.InteropServices;
namespace TestCs
{
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IFireTestCsEvents
{
[DispId(1)]
void NotifyEvent(string message);
}
public delegate void NotifyEventEventHandler(string message);
public interface ITestCs : IDisposable
{
event NotifyEventEventHandler NotifyEvent;
bool Run(string fileName);
void Close();
}
}
这是接口的实现
using System.Runtime.InteropServices;
namespace TestCs
{
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IFireTestCsEvents))]
public class TestCsImp : ITestCs
{
public event NotifyEventEventHandler NotifyEvent;
public TestCsImp()
{
}
public bool Run(string fileName)
{
NotifyEvent?.Invoke(fileName);
return true;
}
public void Close()
{
}
public void Dispose()
{
Close();
}
}
}
对于TestFilter,它基于TransInPlace类,并将TestCsWrapper对象添加到宿主TestC 这是头文件
#pragma once
#import "TestCs.tlb"
using namespace TestCs;
class TestCsWrapper :
public IDispEventSimpleImpl<1, TestCsWrapper, &__uuidof(IFireTestCsEvents)>
{
public:
BEGIN_SINK_MAP(TestCsWrapper)
SINK_ENTRY_INFO(1, __uuidof(IFireTestCsEvents), 0x1, HandleEvent, &NotifyEvent)
END_SINK_MAP()
void __stdcall HandleEvent(BSTR message);
public:
TestCsWrapper();
virtual ~TestCsWrapper();
bool Open();
void Close();
bool IsValid();
bool Load(const wchar_t *fileName);
private:
ITestCsPtr m_pTestCs;
static _ATL_FUNC_INFO NotifyEvent;
};
这是实现
#include "Pch.h"
#include "TestCsWrapper.h"
_ATL_FUNC_INFO TestCsWrapper::NotifyEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };
#define CREATE_CRASH
void __stdcall TestCsWrapper::HandleEvent(BSTR message)
{
::SysFreeString(message);
}
TestCsWrapper::TestCsWrapper()
{
}
TestCsWrapper::~TestCsWrapper()
{
Close();
}
bool TestCsWrapper::Open()
{
m_pTestCs = ITestCsPtr(__uuidof(TestCsImp));
if(!IsValid())
return false;
#ifdef CREATE_CRASH
DispEventAdvise(m_pTestCs);
#endif
return true;
}
void TestCsWrapper::Close()
{
if(IsValid())
{
#ifdef CREATE_CRASH
DispEventUnadvise(m_pTestCs);
#endif
m_pTestCs->Close();
m_pTestCs->Release();
m_pTestCs.Detach();
}
}
bool TestCsWrapper::IsValid()
{
return (m_pTestCs != NULL);
}
bool TestCsWrapper::Load(const wchar_t *fileName)
{
if(!IsValid())
return false;
BSTR bstr = ::SysAllocString(fileName);
VARIANT_BOOL success = m_pTestCs->Run(bstr);
::SysFreeString(bstr);
return success == VARIANT_TRUE;
}
当我禁用DispEventAdvise代码时,应用程序将退出,没有任何异常。
在过滤器的CreateInstance调用中,我添加了以下代码
bool TestFilter::Open()
{
if (!m_testCs.Open())
return false;
m_testCs.Load(L"some messsage");
return true;
}
可以使用完整的Visual Studio解决方案代码进行演示,并且可以在需要时提供
希望找出我做错了什么。 谢谢