c# - 从 C# 调用 C++ 函数时出现访问冲突异常

标签 c# c++ .net pinvoke com-interop

我有以下 C++ 函数(属于 COM 接口(interface),派生自 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. “

我毫无问题地实现了同一接口(interface)的大部分功能,以及该应用程序中的许多其他接口(interface)。这个真的让我很困惑。

非常感谢您对此的帮助..

提前谢谢你。

最佳答案

COM-Interop 有一套相当奇怪的规则,您必须真正“融入其中”才能理解它。许多事情可能会“悄无声息”地出错,你只需要通过艰难的方式来解决它。在类似的情况下,我会通过以下方式尝试解决问题:

  1. 尝试使用 PowerShell 的 COM 接口(interface)。它提供了一个很好的“第二个 POV”,以查看问题是否出在您的 C# 代码中。此外,以这种方式进行测试通常要容易得多,将各种数据插入。

  2. 做一些调试。使用 MessageBox() 技巧在 C++(成员)函数的开头停止执行 C++ 代码,然后附加调试器并查看发生了什么。

  3. 前一点可能很耗时,有时一堆参数和其他状态的 printfs 可以帮助您弄清楚发生了什么。结合 PowerShell,您可以进行大量输入并查看导致问题的原因以及问题的类型。

关于c# - 从 C# 调用 C++ 函数时出现访问冲突异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34730118/

相关文章:

c++ - 使用 std::sort 对二维数组进行排序(基于列)

c# - 如何使用 .NET API 在 Google Drive 中创建文件夹?

c# - '=' 附近的语法不正确。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常

c# - 数据库查询的最佳实践是什么?

c++ - 使用 libvlc 的段错误

c++ - 复制跨步数据(进出 CUDA 设备)的有效方法?

asp.net - 无论如何告诉.net 缓存使用应用程序结构服务器而不是本地内存?

c# - AppDomain 中的静态字段

c# - 如何在 Razor View 中指定全局 MVC 布局而不指定布局路径

c# - 在 Visual Studio C# 中开发 WebService,并从单独的 VS 解决方案中调用它