简体   繁体   English

从C ++编组到C#时CLR崩溃

[英]CLR Crash when Marshalling from C++ to C#

I am making use of an API from Nikon to control a microscope. 我正在使用尼康的API来控制显微镜。 The API is written in C++ while I am implementing a driver in C#. 我用C#实现驱动程序时,API用C ++编写。 To open a connection with the microscope, I must use an Open method with the following Syntax: 要打开与显微镜的连接,我必须使用带有以下语法的Open方法:

lx_result MIC_Open ( const lx_int32 iDeviceIndex, lx_uint64& uiConnectedAccessoryMask, const lx_uint32 uiErrMsgMaxSize, lx_wchar* pwszErrMsg)

If I marshal the technique as follows, the code crashes whenever a Garbage Collection is performed: 如果按如下方式整理技术,则每执行一次垃圾回收,代码就会崩溃:

[DllImport("/filepath/Ni_Mic_Driver.dll")]
protected static extern int MIC_Open ( int deviceIndex , ref ulong accessoryMask , uint errorMessageMaxSize , [MarshalAsAttribute(UnmanagedType.LPWStr)] string error);

A 0xc000005 exception is thrown with error code 80131506, indicating the Garbage Collector has attempted to dispose of an object with an invalid pointer. 引发0xc000005异常,错误代码80131506,表明垃圾收集器已尝试使用无效的指针处理对象。 An error message produced by Visual Studio 2013 indicates: Visual Studio 2013产生的错误消息指示:

"This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshalling errors for COM-Interop or PInvoke, which may corrupt the stack." “此错误可能是CLR或用户代码中不安全或不可验证部分中的错误。此错误的常见来源包括COM-Interop或PInvoke的用户编组错误,这可能会破坏堆栈。”

Following the messages advice, I adjusted the marshalling to the following, which results in no CLR crash. 按照消息的建议,我将编组调整为以下内容,这不会导致CLR崩溃。

[DllImport("/filepath/Ni_Mic_Driver.dll")]
protected static extern int MIC_Open ( int deviceIndex , ref ulong accessoryMask , uint errorMessageMaxSize , [MarshalAsAttribute(UnmanagedType.LPStr)] string error);

I am confused because it is my understanding that wchar* indicates a pointer to a string of null-terminated 16-bit Unicode characters, which should map to UnamagedType.LPWStr. 我很困惑,因为据我了解,wchar *表示一个指向以空值终止的16位Unicode字符的字符串的指针,该字符串应映射到UnamagedType.LPWStr。 However, the code works only if I use UnmanagedType.LPStr. 但是,该代码仅在使用UnmanagedType.LPStr时有效。

The following also works, but should require more work to then extract the corresponding string. 以下内容也可以使用,但需要更多工作才能提取相应的字符串。

[DllImport("/filepath/Ni_Mic_Driver.dll")]
protected static extern int MIC_Open ( int deviceIndex , ref ulong accessoryMask , uint errorMessageMaxSize , IntPtr errorPointer );

Any thoughts on why UnamagedType.LPWStr would cause the crash while it behaves with UnmanagedType.LPStr or IntPtr? 关于UnamagedType.LPWStr为什么与UnmanagedType.LPStr或IntPtr一起运行时会导致崩溃的任何想法?

Thank you to Hans Passant for his recommendation. 感谢Hans Passant的推荐。 I corrected the marshalling as follows: 我更正了编组,如下所示:

[DllImport("/filepath/Ni_Mic_Driver.dll")]
protected static extern int MIC_Open ( int deviceIndex , ref ulong accessoryMask , uint errorMessageMaxSize , [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder errorString);

I then use this method as follows (simplified here for display): 然后,我按如下方式使用此方法(此处简化显示):

NikonDefinitions.accessory = 0;
int errorMessageCapacity = 256;
int nikonErrorMessageMaxSize = errorMessageCapacity - 1;
StringBuilder errorMessage = new StringBuilder(errorMessageCapacity);
int nikonReturn = NikonDefinitions.MIC_Open(Convert.ToInt32(1),ref NikonDefinitions.accessory,nikonErrorMessageMaxSize,errorMessage);

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

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