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