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