C# C++;C语言中的COM接口回调#

C# C++;C语言中的COM接口回调#,c#,c++,com,ms-media-foundation,C#,C++,Com,Ms Media Foundation,我面临的问题来自以下代码: 注意,在答案中(在C代码部分) presentSurfaceECB使用无效返回类型声明 但是,在IDL中,我将其声明为HRESULT presentSurfaceECB(…) 由于这种不匹配,代码实际上可以工作。但是,如果我在C#的接口声明中将返回类型从void更改为int,那么在x86模式下,我最终会遇到访问冲突,而不是x64(x64 ABI不会从堆栈中弹出任何内容,因此在返回类型不匹配时不会崩溃)。i、 e 我还发现,我实际上不必为接口的工作声明它的guid。

我面临的问题来自以下代码:

注意,在答案中(在C代码部分)

presentSurfaceECB
使用无效返回类型声明

但是,在IDL中,我将其声明为
HRESULT presentSurfaceECB(…)

由于这种不匹配,代码实际上可以工作。但是,如果我在C#的接口声明中将返回类型从
void
更改为
int
,那么在x86模式下,我最终会遇到访问冲突,而不是x64(x64 ABI不会从堆栈中弹出任何内容,因此在返回类型不匹配时不会崩溃)。i、 e

我还发现,我实际上不必为接口的工作声明它的guid。 为什么不呢?我怀疑VTable是从接口声明中理解的?在这种情况下,我还应该能够重构我的C++代码,将IDL代码移回C++ +

// [ComVisible(true), ComImport, Guid("B92D8991-6C42-4e51-B942-E61CB8696FCB")] -- this is unnecessary - why?
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[SuppressUnmanagedCodeSecurity]
internal interface IEVRPresenterCallback
{
    [PreserveSig]
    int PresentSurfaceCB(IntPtr pSurface);
}

让我感到害怕的是COM接口指针参数被声明为
uint
;WPF媒体工具包也有这个声明,这大概是正确的。
internal class EVRPresenterCallback : EmideeMediaFoundationLib.IEVRPresenterCallback
{
    public int PresentSurfaceCB(uint pSurface)
    {
        // this crashes with AV after the callback is called!
        // WHY?
    }
}
// [ComVisible(true), ComImport, Guid("B92D8991-6C42-4e51-B942-E61CB8696FCB")] -- this is unnecessary - why?
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[SuppressUnmanagedCodeSecurity]
internal interface IEVRPresenterCallback
{
    [PreserveSig]
    int PresentSurfaceCB(IntPtr pSurface);
}