我正在使用尼康的 API 来控制显微镜。 API 是用 C++ 编写的,而我正在用 C# 实现驱动程序。要打开与显微镜的连接,我必须使用具有以下语法的 Open 方法:
lx_result MIC_Open ( const lx_int32 iDeviceIndex, lx_uint64& uiConnectedAccessoryMask, const lx_uint32 uiErrMsgMaxSize, lx_wchar* pwszErrMsg)
如果我按如下方式编码该技术,则每当执行垃圾收集时代码就会崩溃:
[DllImport("/filepath/Ni_Mic_Driver.dll")]
protected static extern int MIC_Open ( int deviceIndex , ref ulong accessoryMask , uint errorMessageMaxSize , [MarshalAsAttribute(UnmanagedType.LPWStr)] string error);
抛出错误代码为 80131506 的 0xc000005 异常,表示垃圾收集器已尝试处理具有无效指针的对象。 Visual Studio 2013 生成的错误消息表明:
“此错误可能是 CLR 中的错误,或者是用户代码的不安全或不可验证部分中的错误。 此错误的常见来源包括 COM-Interop 或 PInvoke 的用户编码错误,这可能会损坏堆栈。”
按照消息建议,我将编码调整为以下内容,这不会导致 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);
我很困惑,因为我的理解是 wchar* 指示指向以 null 结尾的 16 位 Unicode 字符的字符串的指针,它应该映射到 UnamagedType.LPWStr。但是,该代码仅在我使用 UnmanagedType.LPStr 时才有效。
下面的也可以,但是需要更多的工作才能提取相应的字符串。
[DllImport("/filepath/Ni_Mic_Driver.dll")]
protected static extern int MIC_Open ( int deviceIndex , ref ulong accessoryMask , uint errorMessageMaxSize , IntPtr errorPointer );
有没有想过为什么 UnamagedType.LPWStr 在使用 UnmanagedType.LPStr 或 IntPtr 时会导致崩溃?
最佳答案
感谢 Hans Passant 的推荐。我按如下方式更正了编码:
[DllImport("/filepath/Ni_Mic_Driver.dll")]
protected static extern int MIC_Open ( int deviceIndex , ref ulong accessoryMask , uint errorMessageMaxSize , [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder errorString);
然后我使用这个方法如下(这里简化展示):
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);
关于c# - 从 C++ 编码到 C# 时 CLR 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25794620/