Com IUnknown(IXRApplication)崩溃时的AddRef
我正在调试一个更大的问题,但我已经缩小到一个特定的场景。Com IUnknown(IXRApplication)崩溃时的AddRef,com,windows-embedded-compact,iunknown,silverlight-embedded,Com,Windows Embedded Compact,Iunknown,Silverlight Embedded,我正在调试一个更大的问题,但我已经缩小到一个特定的场景。 首先: 这很好,那么: IUnknown* pUnk; res=pApp->QueryInterface(IID_IUnknown, (void**)&pUnk); 这将执行,甚至返回S_OK,但是pUnk中返回的地址与pApp不一样(正好少4个字节),这是意外的,但从技术上讲不是问题 之后: UINT cnt=pUnk->AddRef(); 这将执行并返回0,但从这一点开始,如果我尝试调用pUnk->Releas
首先: 这很好,那么:
IUnknown* pUnk;
res=pApp->QueryInterface(IID_IUnknown, (void**)&pUnk);
这将执行,甚至返回S_OK
,但是pUnk
中返回的地址与pApp
不一样(正好少4个字节),这是意外的,但从技术上讲不是问题
之后:
UINT cnt=pUnk->AddRef();
这将执行并返回0,但从这一点开始,如果我尝试调用pUnk->Release
或pUnk->QueryInterface
它将崩溃。如果我在pUnk AddRef
之前调用pUnk->Release
,它会运行,但在pUnk->AddRef
任何调用崩溃后都会再次运行。似乎AddRef
实际上正在销毁对象。崩溃似乎是空引用异常
编辑:
因此,在学习了如何在WEC7仿真器上进行调试之后,我发现了问题所在。IUnknown
上的AddRef()
程序集如下所示
xor eax, eax
retn 0x0C
仅此而已,因此每次调用AddRef()
都会损坏堆栈。这很有趣,因为有时它会工作,而有时不会,但事实证明它更多地与堆栈有关,即堆栈分配的变量
我现在不知道该怎么做。由于可移植性问题,我试图避免使用本机包装器,但我不认为只有托管代码可以解决这个问题
另一方面,微软到底在想什么。这是否违反了COM自身的规则。我很难理解他们是如何发布这样破坏堆栈的代码的 首先,QueryInterface很可能为不同的接口返回稍有不同的指针。这就是为什么比较两个COM对象是否相等的正确方法是在两个对象上查询IUnknown,然后比较IUnknown指针。第二个有趣的问题是,为什么AddRef可能返回零。如果对象是单体,这似乎并不罕见。应用程序实例听起来像是一个单例,所以这可能适用?使用接口IXRApplication时会遇到类似的问题吗?@PhilJollans我知道IUnknown指针不必与IXRApplication相同,我只是惊讶于它直接实现了IUnknown,而且只实现了IUnknown。我还知道关于AddRef返回值的规则是无法修复的。关于第三点,我实际上在尝试封送IXRApplication,但是.NETCF坚持查询IUnknown并首先添加引用。
xor eax, eax
retn 0x0C