从 C# 调用 C++ 函数时出现访问冲突异常
Access violation exception when calling C++ function from C#
我有以下 C++ 函数(属于 COM 接口,派生自 IUnknown),我想从 C# 代码中调用它:
记录的 C++ 声明:
HRESULT Function1([in] STRUCT1 *s1, [in, out] STRUCT2 *s2, [in] SIZE_T var1);
工作 C++ 程序中的声明:
STDMETHOD(Function1)(
THIS_
__out STRUCT1 * s1,
__in_ecount_opt(var1) const STRUCT2 * s2,
SIZE_T var1
) PURE;
在 C# 领域我定义如下:
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT1
{
public uint member1; //HRESULT member1
public ulong member2; //SIZE_T member2
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT2
{
public IntPtr member1; //VOID *member1;
public ulong member2; //SIZE_T member2;
public STRUCT3 member3; //STRUCT3 member3;
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT3
{
public int member1; //int member1
}
我用 C# 实现这个函数如下:
[ComImport, ComVisible(false), InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("…")]
public interface Iinterface1
{
……
uint Function1(ref STRUCT1 s1, ref STRUCT2 s2, ulong var1);
……
}
我这样调用函数:
STRUCT1 temp1 = new STRUCT1();
temp1.member1 = 0;
temp1.member2 = 0;
STRUCT2 temp2 = new STRUCT2();
STRUCT3 temp3 = new STRUCT3();
temp3.member1 = 0;
temp2.member1 = IntPtr.Zero;
temp2.member2 = 0;
temp2.member3 = temp3;
ulong var1 = 1;
res1 = COMobject.Function1(ref temp1, ref temp2, var1);
当函数执行时,我得到一个访问冲突异常:
“An unhandled exception of type 'System.AccessViolationException' occurred in prog1.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. “
我毫无问题地实现了同一接口的大部分功能,以及此应用程序中的许多其他接口。这个真让我费解。
非常感谢你的帮助..
提前谢谢你。
COM-Interop 有一套相当奇怪的规则,你必须真正成为 "into it" 才能理解它。很多事情都可能出错 "silently" 而你只需要通过艰难的方式来解决它。在类似的情况下,我会通过以下方式尝试解决问题:
尝试使用 PowerShell 的 COM 接口。它提供了一个很好的 "second POV" 来查看问题是否出在您的 C# 代码中。此外,以这种方式进行测试通常要容易得多,将各种数据推入。
做一些调试。使用 MessageBox() 技巧在 C++(成员)函数的开头停止执行 C++ 代码,然后附加调试器并查看发生了什么。
前一点可能很耗时,有时一堆参数和其他状态的 printfs 可以帮助您弄清楚发生了什么。结合PowerShell,你可以有很多输入,看看是什么原因导致的问题,是什么类型的问题。
我有以下 C++ 函数(属于 COM 接口,派生自 IUnknown),我想从 C# 代码中调用它:
记录的 C++ 声明:
HRESULT Function1([in] STRUCT1 *s1, [in, out] STRUCT2 *s2, [in] SIZE_T var1);
工作 C++ 程序中的声明:
STDMETHOD(Function1)(
THIS_
__out STRUCT1 * s1,
__in_ecount_opt(var1) const STRUCT2 * s2,
SIZE_T var1
) PURE;
在 C# 领域我定义如下:
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT1
{
public uint member1; //HRESULT member1
public ulong member2; //SIZE_T member2
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT2
{
public IntPtr member1; //VOID *member1;
public ulong member2; //SIZE_T member2;
public STRUCT3 member3; //STRUCT3 member3;
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT3
{
public int member1; //int member1
}
我用 C# 实现这个函数如下:
[ComImport, ComVisible(false), InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("…")]
public interface Iinterface1
{
……
uint Function1(ref STRUCT1 s1, ref STRUCT2 s2, ulong var1);
……
}
我这样调用函数:
STRUCT1 temp1 = new STRUCT1();
temp1.member1 = 0;
temp1.member2 = 0;
STRUCT2 temp2 = new STRUCT2();
STRUCT3 temp3 = new STRUCT3();
temp3.member1 = 0;
temp2.member1 = IntPtr.Zero;
temp2.member2 = 0;
temp2.member3 = temp3;
ulong var1 = 1;
res1 = COMobject.Function1(ref temp1, ref temp2, var1);
当函数执行时,我得到一个访问冲突异常:
“An unhandled exception of type 'System.AccessViolationException' occurred in prog1.exe Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. “
我毫无问题地实现了同一接口的大部分功能,以及此应用程序中的许多其他接口。这个真让我费解。
非常感谢你的帮助..
提前谢谢你。
COM-Interop 有一套相当奇怪的规则,你必须真正成为 "into it" 才能理解它。很多事情都可能出错 "silently" 而你只需要通过艰难的方式来解决它。在类似的情况下,我会通过以下方式尝试解决问题:
尝试使用 PowerShell 的 COM 接口。它提供了一个很好的 "second POV" 来查看问题是否出在您的 C# 代码中。此外,以这种方式进行测试通常要容易得多,将各种数据推入。
做一些调试。使用 MessageBox() 技巧在 C++(成员)函数的开头停止执行 C++ 代码,然后附加调试器并查看发生了什么。
前一点可能很耗时,有时一堆参数和其他状态的 printfs 可以帮助您弄清楚发生了什么。结合PowerShell,你可以有很多输入,看看是什么原因导致的问题,是什么类型的问题。