System.AccessViolationException在C ++和C#之间编组

时间:2017-10-19 23:57:29

标签: c# c++ marshalling

我有一个在托管C#应用程序中使用的第三方非托管C ++ DLL。我无法访问C ++代码。

有两种方法被调用。第一个是同步的,按预期工作。第二个是异步的并且导致System.AccessViolationException,它似乎在执行第二个方法期间抛出而不是在其他异步行为期间抛出,但我不确定。

不幸的是,即使是我控制的C#端,也无法共享实际代码。有问题的方法签名有一个输入参数,它是一个混合了整数类型的对象(int,uint,ushort)和一些定义为" char *"的指针。另一种正在运行的方法具有类似的签名,只是一个稍微不同的输入对象来填充。

两种非托管方法都将输入参数值打印到日志文件中,因此我能够验证编组是否正常工作。两个调用的所有输入值在日志中显示正确。但是,我会注意到,对于char *字段,只记录指针本身,而不是它指向的值。我已经验证了非托管C ++代码记录的指针与C#端的指针匹配,但我必须认为它正在读取正确的字节数。每个char *字段中的字节数在其他输入字段中指定,并且这些字节也显示正确。

对于正在运行的方法调用,C ++ DLL在输入参数后打印附加信息,表明方法已成功完成。我不确定第二种方法也有这样的输出,我所知道的是输入参数是异常之前记录的最后一件事。

AccessViolationException的堆栈跟踪中的最后一个条目是:

at System.StubHelpers.ValueClassMarshaler.ClearNative(IntPtr dst, IntPtr pMT)
at MyStuff.MyMethod(String& message) in [path removed]`

MyStuff.MyMethod是我控制的实际C#方法调用的混淆(因此"路径被删除")。看起来在退出C ++方法调用时可能会发生异常,而不是在C ++方法中,但我不确定。

我无法找到ClearNative方法的任何真实文档。我可以猜测它与垃圾收集有关,但我无法确定。我想到这个问题可能与第二个错误调用是异步的事实有关,但异常会在我调用C ++ DLL的行中断执行,所以我不确定。

此时我正在寻找有关ClearNative的任何信息,这些信息可以帮助我缩小问题的性质,或者尝试可以提供更多信息的任何建议。

0 个答案:

没有答案