导入C ++ dll时发生FatalExecutionEngineError

时间:2015-11-23 11:25:29

标签: c# c++ .net wcf

我编写了一个应用程序,它调用用C ++编写的dll中的方法。它是一个WinForms应用程序,它有一个自托管的WCF服务。 WCF方法之一是 定期打电话2-3秒。仅执行WCF部分时不会发生此问题。仅调用SDK函数时,不会出现此问题。但是如果 我启动WCF客户端定期调用我的方法,同时我执行一些SDK函数,10秒后FatalExecutionEngineError(System.ExecutionEngineException)。 引发异常并且应用程序崩溃。我真的不知道可能是什么问题,或者如何解决它。我怀疑它与SDK有某种关系,但我不确定,只是一个 感觉。在SO中阅读相关答案,也许方法导入是错误的?这是我到目前为止所得到的:

WCF类:

[ServiceContract]
public partial interface IWCFSample
{
    [OperationContract]
    string GetData(string param);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public partial class WCFSample : IWCFSample
{
    #region Delegates

    public delegate string OnGetDataDelegate(object sender, string getDataParam);

    #endregion Delegates

    #region Events

    public event OnGetDataDelegate OnGetData;

    #endregion Events

    public string GetData(string serializedGetDataParam)
    {
        string res = string.Empty;
        try
        {
            if (OnGetData != null)
            {
                res = OnGetData(this, (serializedGetDataParam));
            }
        }
        catch
        {
            throw;
        }
        return res;
    }
}

像这样发起:

    private ServiceHost _serviceHost;
    private WCFSample _samplewcf;

    private void Form1_Load(object sender, EventArgs e)
    {
        _samplewcf = new WCFSample();
        _samplewcf.OnGetData += samplewcfOnGetData;

        _serviceHost = new ServiceHost(_samplewcf);
        _serviceHost.Open();
        bw = new BackgroundWorker();
        bw.WorkerSupportsCancellation = true;

        bw.DoWork += (o, args) =>
        {
            WCFSampleClient client = new WCFSampleClient();
            while (true)
            {
                if (bw.CancellationPending)
                {
                    return;
                }

                client.GetData(DateTime.Now.ToString());
                Thread.Sleep(200);
            }
        };
        bw.RunWorkerAsync();
    }

    private string samplewcfOnGetData(object sender, string getDataParam)
    {
        richTextBox1.Text += "GetData Called - " + getDataParam + "\n";
        richTextBox1.SelectionStart = richTextBox1.Text.Length;
        richTextBox1.ScrollToCaret();
        return getDataParam;
    }

与C ++相关的部分很长,但这是我使用的导入。

int OpenDevice (char* strUSBName, int iPortNum )

Imported as:
[DllImport("TP9000.dll")]
public static extern int OpenDevice(string USBNam, int portnum);


int CheckFeeder (int* nCheck)

Imported as:
[DllImport("TP9000.dll")]
public static extern int CheckFeeder(ref int pStatus);


int DP_GetSensorStatus (BYTE *pRailStatus, BYTE *pFeedRollerStatus, BYTE *pTraySensorState)

Imported as:
[DllImport("TP9000.dll")]
public static extern int DP_GetSensorStatus(ref byte pRailStatus, ref byte pFeedRollerStatus, byte[] pTraySensorState);


int PathSenser(int *pStatus)

Imported as:
[DllImport("TP9000.dll")]
public static extern int PathSenser(ref int p1);


int CheckRibbonEx( int *nRibbon, int *nTagRibbon)

Imported as:
[DllImport("TP9000.dll")]
public static extern int CheckRibbonEx(ref int nRibbon, ref int nTagRibbon);


int N_EndOfPrint(int nPanel, int *pPanelCount, int *pJobNo)

Imported as:
[DllImport("TP9000.dll")]
public static extern int N_EndOfPrint(int p1, ref int p2, ref int p3);


int N_PrintJobStatus (int *pJobStatus )

Imported as:
[DllImport("TP9000.dll")]
public static extern int N_PrintJobStatus(int[] p1);

更新

似乎最后一次导入是错误的:

int N_PrintJobStatus (int *pJobStatus )

Imported as:
[DllImport("TP9000.dll")]
public static extern int N_PrintJobStatus(int[] p1);

如果我没有在我的代码中调用此函数,它就不会挂起。但是我应该如何编组呢。文档说:

  

检查打印状态。

     

int N_PrintJobStatus(int * pJobStatus)   参数pJobStatus [out]:

     
      
  • JobStatus [0] = Priter状态:空闲(0x00),打印(0x01),错误打印停止(0xFF)
  •   
  • JobStatus [1] =没有待机作业(出错时,没有暂停作业)
  •   
  • JobStatus [2] =待机作业的数量(包括当前正在运行的作业)
  •   
  • JobStatus [3] =当前操作作业的副本数(打印副本总数)
  •   
  • JobStatus [4] =剩余作业的副本数(剩余计数)
  •   
  • JobStatus [5] =如果显示重新确认检查窗口。 1:AUTO选项显示,2:手动选项显示,0:无检查窗口
  •   
  • JobStatus [6] =它检查错误处理和状态消息级别(1~4),然后在重新打印检查窗口显示0t(自动选项)

         
        
    1. 打开打印机,然后检查功能区。
    2.   
    3. 卡正在弹出
    4.   
    5. 正在同步功能区
    6.   
    7. 如果要重新打印,请按“确定”按钮。(激活“确定”按钮)
    8.   
  •   
     

返回值0:成功。 -1:失败。 (GET_STATUS)

1 个答案:

答案 0 :(得分:0)

好的,没有剩下的代码就无法解决这个问题。 错误代码如下:

int[] nJobSt = { 0, 0, 0, 0, 0, 0 }; //notice that the array length is 6
LastErrorCode = TP9000Dll.N_PrintJobStatus(nJobSt);

从SDK文档中我们应该假设该函数需要7的数组长度 所以正确的代码是:

int[] nJobSt = { 0, 0, 0, 0, 0, 0, 0 }; //notice that the array length is 7
LastErrorCode = TP9000Dll.N_PrintJobStatus(nJobSt);

结论:阅读每个文档3次,永远不要相信随SDK一起提供的示例应用程序。