简体   繁体   English

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

[英]Access violation exception when calling C++ function from C#

I have the following C++ function (belongs to a COM interface, derived from IUnknown), which I want to call from C# code: 我有以下C ++函数(属于一个COM接口,派生自IUnknown),我想从C#代码调用它:

C++ declaration as documented: 记录的C ++声明:

HRESULT Function1([in] STRUCT1 *s1, [in, out] STRUCT2 *s2, [in] SIZE_T var1);

Declaration inside a working C++ program: 工作C ++程序中的声明:

    STDMETHOD(Function1)(
    THIS_
    __out STRUCT1 * s1,
    __in_ecount_opt(var1) const STRUCT2 * s2,
    SIZE_T var1
    ) PURE;

In C# territory I define the following: 在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
}

I implement this function in C# as follows : 我在C#中实现了这个函数,如下所示:

[ComImport, ComVisible(false), InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("…")]
public interface Iinterface1 
{
……


    uint Function1(ref STRUCT1 s1, ref STRUCT2 s2, ulong var1);
……
}

and I invoke the function like this: 我调用这样的函数:

            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);

When function is executed I get an Access Violation Exception : 执行函数时,我收到访问冲突异常:

“An unhandled exception of type 'System.AccessViolationException' occurred in prog1.exe Additional information: Attempted to read or write protected memory. “prog1.exe中发生了'System.AccessViolationException'类型的未处理异常附加信息:尝试读取或写入受保护的内存。 This is often an indication that other memory is corrupt. 这通常表明其他内存已损坏。

I implemented most of functions of the same interface with no problems, as well as a lot of other interfaces in this application. 我实现了同一接口的大多数功能没有问题,以及此应用程序中的许多其他接口。 This one really puzzles me. 这个让我很困惑。

I would really appreciate your help on this.. 我非常感谢你对此的帮助..

Thank you in advance. 先感谢您。

COM-Interop has a rather strange set of rules, you have to really be "into it" to reason about it. COM-Interop有一套相当奇怪的规则,你必须真正“进入它”来推理它。 Many things can go wrong "silently" and you just have to figure it out the hard way. 许多事情可能会“默默地”出错,你只需要艰难地解决它。 In similar situations, here's what I'd do to try to figure things out: 在类似的情况下,这就是我要做的事情,试图解决问题:

  1. Try to use the COM interface from PowerShell. 尝试使用PowerShell的COM接口。 It gives a nice "second POV" to see if the problem may be in your C# code. 它提供了一个很好的“第二个POV”来查看问题是否在您的C#代码中。 Also, it's usually much easier to do testing this way, pushing various data in. 此外,以这种方式进行测试通常要容易得多,推送各种数据。

  2. Do some debugging. 做一些调试。 Use the MessageBox() trick to halt the execution of C++ code at the start of the C++ (member) function, then attach the debugger and see what's going on. 使用MessageBox()技巧在C ++(成员)函数的开头停止执行C ++代码,然后附加调试器并查看发生了什么。

  3. The previous point can be time consuming, sometimes a bunch of printfs of the parameters and other state can help you figure out what's going on. 前一点可能很耗时,有时一堆参数和其他状态的printf可以帮助你弄清楚发生了什么。 Combined with PowerShell, you can have a lot of inputs and see which cause issues and what kind of issues. 结合PowerShell,您可以获得大量输入,并查看导致问题和问题的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM