2017-08-25 121 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标签中,看看是不对的。 –