如何在C#中编组SIZE结构?

时间:2012-08-06 07:06:19

标签: c# c++ interop com-interop

我正在尝试编组以下C ++函数:

STDMETHODIMP CPushSource::SetSize(SIZE *pSize)
{
    CMutexLock lock(&m_csShared);
    CheckPointer(pSize, E_POINTER);

    m_iImageWidth = pSize->cx;
    m_iImageHeight = pSize->cy;

    saveSettings();

    return S_OK;
}

使用以下C#代码:

[ComImport, Guid("1b1afbaf-cb92-42da-8307-5a7be8c2b4b0")]
public interface ISCFHSettings
{
    [PreserveSig]
    int SetSize([In, MarshalAs(UnmanagedType.Struct)] Size size);
}

我试图用以下代码调用它:

m_desktopFilter.SetSize(new Size(320,240));

我对这个C ++ / C#interop的东西很陌生,所以任何能指出我正确方向的人都非常感激。

我得到的错误也是:

  

尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

如果重要的话,这是我尝试使用DirectShow过滤器的简单包装器。过滤器是SCFH-DSF。

我也试过

[ComImport, Guid("1b1afbaf-cb92-42da-8307-5a7be8c2b4b0")]
public interface ISCFHSettings
{
    [PreserveSig]
    int SetSize([In, MarshalAs(UnmanagedType.Struct)] MySize size);
}

[StructLayout(LayoutKind.Sequential)]
public struct MySize
{
    public int cx;
    public int cy;
}

和调用代码

MySize sz = new MySize();
sz.cx = 320;
sz.cy = 240;
m_desktopFilter.SetSize(sz);

这对我也不起作用。

[ComImport, Guid("1b1afbaf-cb92-42da-8307-5a7be8c2b4b0")]
public interface ISCFHSettings
{
    [PreserveSig]
    int SetSize(ref MySize size);
}

2 个答案:

答案 0 :(得分:1)

签名中的[MarshalAs(UnmanagedType.Struct)]不正确。该函数需要一个指向SIZE的指针,因此您需要定义它(如您所做)并通过引用传递它而不使用其他编组属性。

我希望您应该像这样定义界面:

[ComImport, Guid("1b1afbaf-cb92-42da-8307-5a7be8c2b4b0")] 
public interface ISCFHSettings 
{ 

    int SetSize(MySize size); 

}

[MarshalAs(UnmanagedType.Struct)]实际上与VARIANT编组相关,但名称很差。

答案 1 :(得分:1)

如上所述,您应该能够使其与ref一起使用,但由于您仍然遇到麻烦,这里有一个最小的完整程序可以正常工作。你可以扩展它,直到你得到你想要的东西。

C#:

using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    public struct mySize
    {
        public int x, y;
    }

    static class Program
    {
        [DllImport("ClassLibrary.dll")]
        static extern int getX(ref mySize size);

        static void Main(string[] args)
        {
            var size = new mySize { x=100, y=200 };
            int x = getX(ref size);
            Debug.Assert(x == 100);
        }
    }
}

VC ++:

struct mySize
{
    int x, y;
};

extern "C" __declspec(dllexport)
int  __stdcall getX(mySize *pSize)
{
    return pSize->x;
}