【问题标题】:Application Crashes when Code Optimization option is enabled启用代码优化选项时应用程序崩溃
【发布时间】:2010-07-16 20:19:49
【问题描述】:

我遇到以下问题:

我正在开发一个 C# 应用程序,它需要不安全的代码来调用非托管 c++ 函数。结构是:

[StructLayout(LayoutKind.Sequential)]
unsafe struct DataStruct
{
    public UInt16 index;
    public UInt16 response;
    public byte* addr; //this is a pointer to a byte array which stores some some data.
}

这就是我导入函数的方式:

[DllImport("imagedrv.dll", EntryPoint = "SendCommand", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
private static extern int SendCommand([MarshalAs(UnmanagedType.Struct, SizeConst = 8)]ref DataStruct s);

该函数已成功从线程调用,我得到了预期的结果,但问题是每当我与 Windows.Form 表单交互时,整个应用程序都会崩溃。如果我将鼠标移到它上面或与我的 contextmenustrip 控件交互,这并不重要。如果我不与表单交互,程序运行良好。

调用示例:

DataStruct s;
byte[] buffer = new byte[512];

s.index = 0x03;
s.response = 0;
fixed (byte* pBuffer = buffer) s.addr = pBuffer;
System.Console.WriteLine(SendCommand(ref s));

奇怪的是,如果我在项目属性中禁用代码优化选项,程序运行正常!

会发生什么?

【问题讨论】:

    标签: c# optimization crash unmanaged


    【解决方案1】:

    尝试在固定块内移动 SendCommand 调用:

    DataStruct s;
    byte[] buffer = new byte[512];
    
    s.index = 0x03;
    s.response = 0;
    fixed (byte* pBuffer = buffer) {
        s.addr = pBuffer;
        System.Console.WriteLine(SendCommand(ref s));
    }
    

    否则,事情可能会在你意想不到的情况下发生变化。

    【讨论】:

      【解决方案2】:

      您的 buffer 数组正在被垃圾回收。

      添加

      GC.KeepAlive(buffer);
      

      在 P/Invoke 调用之后。

      编辑:您还需要固定它。

      【讨论】:

      • 感谢您的回答。正如 SLaks 指出的那样,我的缓冲区正在被垃圾收集,他的代码行解决了我的问题。谢谢!
      • 这还不够,正如 Mike 的回答所指出的那样,因为它不会阻止 GC 移动数组。
      猜你喜欢
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多