2017-08-25 79 views
1

新手到C#。我寫了一個WDF驅動程序和DLL的工作。我正在C#中創建一個應用程序來通過DLL訪問硬件。有一個特定的函數在第一次調用之後不久導致ExecutionEngineException。下面是從DLL中的函數定義:C#接口到DLL和ExecutionEngineException

DECLDIR int ReadDatagram(int channel, unsigned long *msgID, unsigned int *msgType, int *msgLen, unsigned int *data); 

在我的C#應用​​程序代碼,我導入此功能與下面幾行:

[DllImport("pcmcanDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
internal static extern int ReadDatagram(int channel, ref uint msgID, ref uint msgType, ref int msgLen, uint[] data); 

當我啓動應用程序,並打開一個通道,這個功能由定時器週期性地調用。經過短暫的無限期後,我收到以下異常消息。如果我註釋掉他調用這個函數,應用程序永遠不會有問題。

Mesage:類型System.ExecutionEngineException「未處理的異常出現在mscorlib.dll

我的應用程序代碼是在這裏。我相信我正確地處理了指針參數,因爲偶爾這會工作幾次,並且數據在這些停止時是好的。欣賞任何見解。

private void rcvTimer_Tick(object sender, EventArgs e) 
{ 
    int channel = 1; 
    String dsplyString = "Packet Received\n"; 
    uint msgID = 0, msgType = 0; 
    int msgLen = 0; 
    uint[] data = new uint[8]; 
    ErrorTypes dllReturn = ErrorTypes.RCV_BUFFER_EMPTY; 

    do 
    { 
     dllReturn = (ErrorTypes)NativeMethods.ReadDatagram(channel, ref msgID, ref msgType, ref msgLen, data); 

     if (dllReturn != ErrorTypes.SUCCESS && dllReturn != ErrorTypes.RCV_BUFFER_EMPTY) 
     { 
      MessageBox.Show("Error receiving packet.", "Receipt Error", 
       MessageBoxButtons.OK, MessageBoxIcon.Error); 
      break; 
     } 
     else if (dllReturn == ErrorTypes.SUCCESS) 
     { 
      dsplyString = String.Format("{0} {1} {2} {3}\n", channel, msgID, msgType, msgLen); 
     } 
    } while (dllReturn != ErrorTypes.RCV_BUFFER_EMPTY); 

} 
+0

也看到了以下錯誤消息:類型的未處理的異常「System.AccessViolationException」發生在mscorlib.dll 其他信息:試圖讀取或寫入保護內存。這通常表明其他內存已損壞。 – Paul

+0

很難說你做錯了什麼,因爲沒有規定如何調用DLL。僅僅知道參數的類型是不夠的。 –

回答

-1

嘗試以下

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 

     } 

    } 
    public enum ErrorTypes : int 
    { 
     RCV_BUFFER_EMPTY = 0, 
     SUCCESS = 1 
    } 
    public class Test 
    { 
     [DllImport("pcmcanDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
     internal static extern int ReadDatagram(int channel, ref uint msgID, IntPtr msgType, ref int msgLen, IntPtr dataPtr); 

     private void rcvTimer_Tick(object sender, EventArgs e) 
     { 
      int channel = 1; 
      String dsplyString = "Packet Received\n"; 
      uint msgID = 0; 
      uint msgType = 0; 
      int msgLen = 0; 
      uint[] data = new uint[8]; 


      ErrorTypes dllReturn = ErrorTypes.RCV_BUFFER_EMPTY; 

      IntPtr dataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(data)); 
      IntPtr msgTypePtr = Marshal.AllocHGlobal(Marshal.SizeOf(msgType)); 
      do 
      { 
       Marshal.StructureToPtr(msgType, msgTypePtr, true); 
       Marshal.StructureToPtr(data, dataPtr, true); 
       dllReturn = (ErrorTypes)ReadDatagram(channel, ref msgID, msgTypePtr, ref msgLen, dataPtr); 


       if (dllReturn != ErrorTypes.SUCCESS && dllReturn != ErrorTypes.RCV_BUFFER_EMPTY) 
       { 
        MessageBox.Show("Error receiving packet.", "Receipt Error", 
         MessageBoxButtons.OK, MessageBoxIcon.Error); 
        break; 
       } 
       else if (dllReturn == ErrorTypes.SUCCESS) 
       { 
        dsplyString = String.Format("{0} {1} {2} {3}\n", channel, msgID, msgType, msgLen); 
       } 
      } while (dllReturn != ErrorTypes.RCV_BUFFER_EMPTY); 

      Marshal.FreeHGlobal(dataPtr); 
      Marshal.FreeHGlobal(msgTypePtr); 

     } 
    } 
} 
+0

很多錯誤在這裏 –

+0

你甚至沒有嘗試代碼,所以你怎麼知道它不工作?你所做的只是做出負面評論,絕不會發布真正的解決方案。 – jdweng

+0

看看我的記錄在pinvoke標籤中,看看是不對的。 –