1

TEKTRONIX 020-2924-XX DPO DEMO 2 ボードから USB 経由でメッセージを送信する USB2-F-7x02 CANBus アダプタ用に Microsoft Visual C# 2010 Express でコードを書いています。

以下の CANSnifferForm.cs というコードは、CANBus API と対話する GUI を使用します。Run_Click は、アダプターがリッスンを開始する (canplus_Listen) 前にユーザーが [実行] をクリックした後、アダプターを開きます (canplus_open)。次に、コールバック スレッド (setReceiveCallBackThread) が実行され、コールバックを呼び出す setReceiveCallBack が呼び出されます。msg オブジェクトにはメッセージが含まれます。私の問題は、メッセージからこの情報を取得し、それを DataGridView (dataGridView1) に追加することにあります。

多くの可能性を検討しました。

最も明白なものは、「this.dataGridView1.Rows.Add(msg.id, msg.len, msg.timestamp);」と記述して、単純に dataGridView に行を追加することでした。コールバックで。ただし、コールバックは実際には静的ですが、dataGridView1 はそうではありません。残念ながら、 static キーワードを削除することはできません。これは、呼び出し元の関数で構文エラーが発生するためです。また、dataGridView1 を静的として宣言することはできません。これは、デザイン フォーム ファイルの初期化で構文エラーが発生するためです。

2 番目のオプションは、ファイルを開いて書き込むことでした。しかし、StreamWriter オブジェクトを宣言して使用すると、コールバックが静的に宣言されているというエラーが発生しました。そこで、コンソールに出力し、トレースを使用してファイルにリダイレクトすることにしました (Console.WriteLine は静的ではないため)。ここでトレースに関する議論を見つけました:

トレースします。

ただし、プログラムはこのファイルを解析し、スレッドの開始直後に dataGridView に出力する必要があります。これは、スレッドがファイルに書き込むときに、StreamReader オブジェクトが同時にファイルから読み取るため、データが複雑になる可能性があることを意味します。これにより、実行時にプログラムが応答しなくなりました。

そのため、最終的に静的配列を宣言し、コールバックに入力することを検討しました。配列の初期化に問題がありました。ただし、ループで解析して dataGridView に配置するには、最初に配列の大きさを知る必要があります。ループを使用して解析すると、サイズが変化します。

私はこれで忍耐力を失い始めています。だから私はスタックオーバーフローに私の質問を提示しています.

次の 3 つのコードには、問題の分析に必要なすべてが含まれている必要があります。EASYSYNC.msg は EASYSYNC.cs で宣言されています。私が行っている主なコーディングは CANSnifferForm.cs です。

// CANSnifferForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;

namespace WindowsFormsApplication1
{

    public partial class CANSnifferForm : Form
    {

        // per the api document. "This is a blocking call and must be called on a separate thread."
        // the code previously after setCallback... was never being reached because the call is   blocking.
        // this calls the setCallbackThread function in another thread so processing can continue.
        Thread setReceiveCallBackThread;
        //static int arrSize = 0;

        int handle, listenReturnValue;
        TextWriter tw = new StreamWriter("dataGridView1.txt");

        public CANSnifferForm()
        {
            InitializeComponent();
        }


        private static void callback(ref EASYSYNC.CANMsg msg)
        {
            // Populate something perhaps??
        }

        EASYSYNC.CallbackDelegate del = new EASYSYNC.CallbackDelegate(callback);

        private void Run_Click(object sender, EventArgs e)
        {

            this.CANSnifferStatusBox.AppendText("CAN closed");
            this.ProcessStatusBox.AppendText("Stopped");
            EASYSYNC.CANMsg msg = new EASYSYNC.CANMsg();
            msg.id = 1;
            msg.timestamp = 2;
            msg.flags = 3;
            msg.len = 4;
            msg.data = 5;
            handle = EASYSYNC.canplus_Open(IntPtr.Zero, "1000", IntPtr.Zero, IntPtr.Zero, 0);

            if (handle < 0)
                this.ErrorBox.AppendText("Error opening CAN");

            this.CANSnifferStatusBox.Clear();
            this.CANSnifferStatusBox.AppendText("CAN open");


            setReceiveCallBackThread = new Thread(() => EASYSYNC.canplus_setReceiveCallBack(handle, callback));
            listenReturnValue = EASYSYNC.canplus_Listen(handle);

            if (listenReturnValue < 0)
            {
                this.ErrorBox.Clear();
                this.ErrorBox.AppendText("Error setting listen mode\n");
                EASYSYNC.canplus_Close(listenReturnValue);
                this.CANSnifferStatusBox.Clear();
                this.CANSnifferStatusBox.AppendText("CAN closed\n");
            }

            this.CANSnifferStatusBox.Clear();
            this.CANSnifferStatusBox.AppendText("CAN Listening\n");

            setReceiveCallBackThread.Start();
            this.ProcessStatusBox.Clear();
            this.ProcessStatusBox.AppendText("Running\n");

            // Insert loop here to populate dataGridView
            // this.dataGridView1.Rows.Add(msg.id, msg.len, msg.timestamp);



        }

      private void Stop_Click(object sender, EventArgs e)
        {
           setReceiveCallBackThread.Abort(); // Stop thread
           this.ProcessStatusBox.Clear();
           this.ProcessStatusBox.AppendText("Stopped");
           EASYSYNC.canplus_Close(listenReturnValue);
           this.CANSnifferStatusBox.Clear();
           this.CANSnifferStatusBox.AppendText("CAN closed");

        }
}


// CANSnifferProgram.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    static class CANSnifferProgram
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new CANSnifferForm());


        }
    }
}

// EASYSYNC.cs

using System;
using System.Runtime.InteropServices;
using System.Text;


internal class EASYSYNC
{
    public const string CAN_BitRate_100K = "100";
    public const string CAN_BitRate_10K = "10";
    public const string CAN_BitRate_125K = "125";
    public const string CAN_BitRate_1M = "1000";
    public const string CAN_BitRate_20K = "20";
    public const string CAN_BitRate_250K = "250";
    public const string CAN_BitRate_500K = "500";
    public const string CAN_BitRate_50K = "50";
    public const string CAN_BitRate_800K = "800";
    public const byte CANMSG_EXTENDED = 0x80;
    public const byte CANMSG_RTR = 0x40;
    public const uint canplus_ACCEPTANCE_CODE_ALL = 0;
    public const uint canplus_ACCEPTANCE_MASK_ALL = uint.MaxValue;
    public const byte CANPLUS_FLAG_BLOCK = 4;
    public const byte CANPLUS_FLAG_NO_LOCAL_SEND = 0x10;
    public const byte CANPLUS_FLAG_QUEUE_REPLACE = 2;
    public const byte CANPLUS_FLAG_SLOW = 8;
    public const byte CANPLUS_FLAG_TIMESTAMP = 1;
    public const byte CANSTATUS_EWARN = 1;
    public const byte CANSTATUS_RXB0OVFL = 0x80;
    public const byte CANSTATUS_RXB1OVFL = 0x40;
    public const byte CANSTATUS_RXBP = 8;
    public const byte CANSTATUS_RXWARN = 2;
    public const byte CANSTATUS_TXBO = 0x20;
    public const byte CANSTATUS_TXBP = 0x10;
    public const byte CANSTATUS_TXWARN = 4;
    public const int ERROR_CANPLUS_COMMAND_SUBSYSTEM = -3;
    public const int ERROR_CANPLUS_FAIL = -1;
    public const int ERROR_CANPLUS_INVALID_HARDWARE = -11;
    public const int ERROR_CANPLUS_INVALID_PARAM = -6;
    public const int ERROR_CANPLUS_MEMORY_ERROR = -8;
    public const int ERROR_CANPLUS_NO_DEVICE = -9;
    public const int ERROR_CANPLUS_NO_MESSAGE = -7;
    public const int ERROR_CANPLUS_NOT_OPEN = -4;
    public const int ERROR_CANPLUS_OK = 1;
    public const int ERROR_CANPLUS_OPEN_SUBSYSTEM = -2;
    public const int ERROR_CANPLUS_TIMEOUT = -10;
    public const int ERROR_CANPLUS_TX_FIFO_FULL = -5;
    public const uint FLUSH_DONTWAIT = 1;
    public const uint FLUSH_EMPTY_INQUEUE = 2;
    public const uint FLUSH_WAIT = 0;

    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Close(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Flush(int h);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_getFirstAdapter(StringBuilder szAdapter, int size);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_getNextAdapter(StringBuilder szAdapter, int size);
    [DllImport("USBCanPlusDllF.dll", EntryPoint="canplus_VersionInfo")]
    public static extern int canplus_getVersionInfo(int handle, StringBuilder verinfo);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Listen(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Open(IntPtr szID, string szBitrate, IntPtr acceptance_code, IntPtr acceptance_mask, uint flags);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Open(string szID, string szBitrate, IntPtr acceptance_code, IntPtr acceptance_mask, uint flags);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Open(string szID, string szBitrate, string acceptance_code, string acceptance_mask, uint flags);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Read(int handle, ref CANMsg msg);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_ReadN(int handle, ref CANMsg msg);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Reset(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_SetTimeouts(int handle, uint receiveTimeout, uint transmitTimeout);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Status(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Write(int handle, ref CANMsg msg);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_setReceiveCallBack(int handle, CallbackDelegate callback);

    [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
    public delegate void CallbackDelegate(ref CANMsg msg);

    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct CANMsg
    {
        public uint id;
        public uint timestamp;
        public byte flags;
        public byte len;
        public ulong data;
    }

    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct CANMsgEx
    {
        public uint id;
        public uint timestamp;
        public byte flags;
        public byte len;
    }
}


// CANSnifferForm.Designer.cs
namespace WindowsFormsApplication1
{
    partial class CANSnifferForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.RunRestart = new System.Windows.Forms.Button();
            this.Stop = new System.Windows.Forms.Button();
            this.Pause = new System.Windows.Forms.Button();
            this.Resume = new System.Windows.Forms.Button();
            this.FilterLength = new System.Windows.Forms.TextBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.FilterByID = new System.Windows.Forms.Label();
            this.FilterbyLength = new System.Windows.Forms.Label();
            this.CANSnifferStatus = new System.Windows.Forms.Label();
            this.ErrorBox = new System.Windows.Forms.TextBox();
            this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.ID = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Length = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Data = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.TimeStamp = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.ErrorMessage = new System.Windows.Forms.Label();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.ProcessStatus = new System.Windows.Forms.Label();
            this.ProcessStatusBox = new System.Windows.Forms.TextBox();
            this.CANSnifferStatusBox = new System.Windows.Forms.TextBox();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout();
            // 
            // RunRestart
            // 
            this.RunRestart.Location = new System.Drawing.Point(56, 80);
            this.RunRestart.Margin = new System.Windows.Forms.Padding(4);
            this.RunRestart.Name = "RunRestart";
            this.RunRestart.Size = new System.Drawing.Size(125, 39);
            this.RunRestart.TabIndex = 0;
            this.RunRestart.Text = "Run / Restart";
            this.RunRestart.UseVisualStyleBackColor = true;
            this.RunRestart.Click += new System.EventHandler(this.Run_Click);
            // 
            // Stop
            // 
            this.Stop.Location = new System.Drawing.Point(1009, 80);
            this.Stop.Name = "Stop";
            this.Stop.Size = new System.Drawing.Size(154, 39);
            this.Stop.TabIndex = 12;
            this.Stop.Text = "Stop";
            this.Stop.UseVisualStyleBackColor = true;
            this.Stop.Click += new System.EventHandler(this.Stop_Click);
            // 
            // Pause
            // 
            this.Pause.Location = new System.Drawing.Point(232, 80);
            this.Pause.Name = "Pause";
            this.Pause.Size = new System.Drawing.Size(120, 39);
            this.Pause.TabIndex = 13;
            this.Pause.Text = "Pause";
            this.Pause.UseVisualStyleBackColor = true;
            this.Pause.Click += new System.EventHandler(this.Pause_Click);
            // 
            // Resume
            // 
            this.Resume.Location = new System.Drawing.Point(411, 80);
            this.Resume.Name = "Resume";
            this.Resume.Size = new System.Drawing.Size(122, 39);
            this.Resume.TabIndex = 14;
            this.Resume.Text = "Resume";
            this.Resume.UseVisualStyleBackColor = true;
            this.Resume.Click += new System.EventHandler(this.Resume_Click);
            // 
            // FilterLength
            // 
            this.FilterLength.Location = new System.Drawing.Point(620, 88);
            this.FilterLength.Name = "FilterLength";
            this.FilterLength.Size = new System.Drawing.Size(161, 22);
            this.FilterLength.TabIndex = 16;
            this.FilterLength.TextChanged += new System.EventHandler(this.FilterLength_TextChanged);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(850, 88);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(57, 22);
            this.textBox1.TabIndex = 17;
            // 
            // FilterByID
            // 
            this.FilterByID.AutoSize = true;
            this.FilterByID.Location = new System.Drawing.Point(617, 63);
            this.FilterByID.Name = "FilterByID";
            this.FilterByID.Size = new System.Drawing.Size(75, 17);
            this.FilterByID.TabIndex = 18;
            this.FilterByID.Text = "Filter by ID";
            this.FilterByID.Click += new System.EventHandler(this.FilterByID_Click);
            // 
            // FilterbyLength
            // 
            this.FilterbyLength.AutoSize = true;
            this.FilterbyLength.Location = new System.Drawing.Point(847, 63);
            this.FilterbyLength.Name = "FilterbyLength";
            this.FilterbyLength.Size = new System.Drawing.Size(106, 17);
            this.FilterbyLength.TabIndex = 19;
            this.FilterbyLength.Text = "Filter by Length";
            this.FilterbyLength.Click += new System.EventHandler(this.FilterbyLength_Click);
            // 
            // CANSnifferStatus
            // 
            this.CANSnifferStatus.AutoSize = true;
            this.CANSnifferStatus.Location = new System.Drawing.Point(53, 9);
            this.CANSnifferStatus.Name = "CANSnifferStatus";
            this.CANSnifferStatus.Size = new System.Drawing.Size(121, 17);
            this.CANSnifferStatus.TabIndex = 21;
            this.CANSnifferStatus.Text = "CANSniffer Status";
            this.CANSnifferStatus.Click += new System.EventHandler(this.CANSnifferStatus_Click);
            // 
            // ErrorBox
            // 
            this.ErrorBox.BackColor = System.Drawing.SystemColors.Control;
            this.ErrorBox.Location = new System.Drawing.Point(180, 35);
            this.ErrorBox.Name = "ErrorBox";
            this.ErrorBox.Size = new System.Drawing.Size(220, 22);
            this.ErrorBox.TabIndex = 22;
            // 
            // dataGridViewTextBoxColumn1
            // 
            this.dataGridViewTextBoxColumn1.DataPropertyName = "Target";
            this.dataGridViewTextBoxColumn1.HeaderText = "Target";
            this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
            this.dataGridViewTextBoxColumn1.ReadOnly = true;
            // 
            // dataGridView1
            // 
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.ID,
            this.Length,
            this.Data,
            this.TimeStamp});
            this.dataGridView1.Location = new System.Drawing.Point(17, 156);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.RowTemplate.Height = 24;
            this.dataGridView1.Size = new System.Drawing.Size(1146, 388);
            this.dataGridView1.TabIndex = 23;
            this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
            // 
            // ID
            // 
            this.ID.HeaderText = "ID";
            this.ID.Name = "ID";
            this.ID.Width = 200;
            // 
            // Length
            // 
            this.Length.HeaderText = "Length";
            this.Length.Name = "Length";
            // 
            // Data
            // 
            this.Data.HeaderText = "Data";
            this.Data.Name = "Data";
            this.Data.Width = 600;
            // 
            // TimeStamp
            // 
            this.TimeStamp.HeaderText = "Time Stamp";
            this.TimeStamp.Name = "TimeStamp";
            this.TimeStamp.Width = 200;
            // 
            // ErrorMessage
            // 
            this.ErrorMessage.AutoSize = true;
            this.ErrorMessage.Location = new System.Drawing.Point(53, 35);
            this.ErrorMessage.Name = "ErrorMessage";
            this.ErrorMessage.Size = new System.Drawing.Size(101, 17);
            this.ErrorMessage.TabIndex = 24;
            this.ErrorMessage.Text = "Error Message";
            // 
            // progressBar1
            // 
            this.progressBar1.Location = new System.Drawing.Point(17, 133);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Size = new System.Drawing.Size(69, 17);
            this.progressBar1.TabIndex = 26;
            // 
            // ProcessStatus
            // 
            this.ProcessStatus.AutoSize = true;
            this.ProcessStatus.Location = new System.Drawing.Point(617, 12);
            this.ProcessStatus.Name = "ProcessStatus";
            this.ProcessStatus.Size = new System.Drawing.Size(103, 17);
            this.ProcessStatus.TabIndex = 28;
            this.ProcessStatus.Text = "Process Status";
            // 
            // ProcessStatusBox
            // 
            this.ProcessStatusBox.BackColor = System.Drawing.SystemColors.Menu;
            this.ProcessStatusBox.Location = new System.Drawing.Point(726, 12);
            this.ProcessStatusBox.Name = "ProcessStatusBox";
            this.ProcessStatusBox.Size = new System.Drawing.Size(148, 22);
            this.ProcessStatusBox.TabIndex = 29;
            this.ProcessStatusBox.TextChanged += new System.EventHandler(this.ProcessStatusBox_TextChanged);
            // 
            // CANSnifferStatusBox
            // 
            this.CANSnifferStatusBox.BackColor = System.Drawing.SystemColors.Menu;
            this.CANSnifferStatusBox.Location = new System.Drawing.Point(180, 6);
            this.CANSnifferStatusBox.Name = "CANSnifferStatusBox";
            this.CANSnifferStatusBox.Size = new System.Drawing.Size(163, 22);
            this.CANSnifferStatusBox.TabIndex = 31;
            this.CANSnifferStatusBox.TextChanged += new System.EventHandler(this.textBox2_TextChanged);
            // 
            // CANSnifferForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1357, 533);
            this.Controls.Add(this.CANSnifferStatusBox);
            this.Controls.Add(this.ProcessStatusBox);
            this.Controls.Add(this.ProcessStatus);
            this.Controls.Add(this.progressBar1);
            this.Controls.Add(this.ErrorMessage);
            this.Controls.Add(this.dataGridView1);
            this.Controls.Add(this.ErrorBox);
            this.Controls.Add(this.CANSnifferStatus);
            this.Controls.Add(this.FilterbyLength);
            this.Controls.Add(this.FilterByID);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.FilterLength);
            this.Controls.Add(this.Resume);
            this.Controls.Add(this.Pause);
            this.Controls.Add(this.Stop);
            this.Controls.Add(this.RunRestart);
            this.Margin = new System.Windows.Forms.Padding(4);
            this.Name = "CANSnifferForm";
            this.Text = "CAN Sniffer ";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button RunRestart;
        private System.Windows.Forms.Button Stop;
        private System.Windows.Forms.Button Pause;
        private System.Windows.Forms.Button Resume;
        private System.Windows.Forms.TextBox FilterLength;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Label FilterByID;
        private System.Windows.Forms.Label FilterbyLength;
        private System.Windows.Forms.Label CANSnifferStatus;
        private System.Windows.Forms.TextBox ErrorBox;
        private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
        private System.Windows.Forms.DataGridView dataGridView1;
        private System.Windows.Forms.DataGridViewTextBoxColumn ID;
        private System.Windows.Forms.DataGridViewTextBoxColumn Length;
        private System.Windows.Forms.DataGridViewTextBoxColumn Data;
        private System.Windows.Forms.DataGridViewTextBoxColumn TimeStamp;
        private System.Windows.Forms.Label ErrorMessage;
        private System.Windows.Forms.ProgressBar progressBar1;
        private System.Windows.Forms.Label ProcessStatus;
        private System.Windows.Forms.TextBox ProcessStatusBox;
        private System.Windows.Forms.TextBox CANSnifferStatusBox;
    }
}
4

1 に答える 1

1

実際、コールバック メソッドを非静的にすることができます。デリゲートは、"this call" を行うためにサンクでマーシャリングされます。秘訣は、フォームのコンストラクターの外でそのデリゲートを初期化できないことです。その理由は、ctor の外には「これ」がないからです。次のように宣言します。

private EASYSYNC.CallbackDelegate del;

次に、コンストラクターで初期化します。

del = new EASYSYNC.CallbackDelegate(callback);

呼び出すときは、「callback」ではなく「del」を渡すようにしてくださいEASYSYNC.canplus_setReceiveCallBack(現在、間違っています)。アンマネージ コードに渡されるときに、このデリゲートへの参照を保持することをお勧めします。「コールバック」を渡すと、デリゲートが作成されましたが、参照を保持する機会がありませんでした。その参照をコールバック内で再利用します。

注意が必要なのは、コールバック メソッドにあります。別のスレッドから DGV (またはバインドされたコンテナー) にアイテムを追加することはできません。UI コントロールは、それらが作成された UI スレッド以外のスレッドからはアクセスできません。別のスレッドで実行しているかどうかを簡単に確認できます。実行している場合は、BeginInvoke を使用して、今回は UI スレッドから自分自身を再度呼び出します。

private void callback(ref EASYSYNC.CANMsg msg)
{
    if (InvokeRequired)
        BeginInvoke(del, msg);
    else
    {
        // Now you can add items to the DGV
    }
}
于 2012-07-19T21:57:41.860 に答える