C#与DLL和ExecutionEngineException的接口

时间:2017-08-25 20:12:23

标签: c# .net exception dll

新手到C#。我写了一个WDF驱动程序和DLL工作。我在C#中创建一个应用程序来通过DLL访问硬件。有一个特定的函数在第一次调用后很快就会导致ExecutionEngineException。这是DLL中的函数定义:

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);

}

1 个答案:

答案 0 :(得分:-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);

        }
    }
}