我正在尝试编组以下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);
}
答案 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;
}