はじめに
知識が浅いため、間違った言葉、表現、そもそも認識間違いがあるかも知れません。
その際はご指摘頂けますと勉強になりますので有り難いです。どうぞ宜しくお願い致します。
実現したいこと
WindowsフォームアプリケーションにてDllの使い方を知りたいです。
前提
現在、WindowsにてI/O信号を制御するアプリケーションを作成しています。
I/O信号はTCTEC社のTOP16というUSB I/Oボードを使用します。
販売元のエレファインにて、C#用サンプルコードと使用するDllファイルが提供されており、動作確認をしたところコンソールアプリだったので、これをベースにフォームアプリを作っています。
現在の目標は、同様に提供されているTop16 Manager2.3と同じ機能を実現したいと考えています。
このTop16 Manager2.3の動きを簡単にですがご説明しますと、アプリ起動時にTop16ボードが繋がっていれば上記のようにBorad名の表示とin 1-8の状態検出します。
インプット信号はプルアップしているのでインプットがOFF時にハイレベルとなり色が紫色に変わっています。
起動後に例えばインプット in 1を外部スイッチからONにするとリアルタイムにセルの色が白くなります。
ただし仕様なのか起動後にin 1 - in 8のセルをクリックしなければそれぞれのGainの値は表示はされませんが、一度表示するとその後はリアルタイムに値を表示します。
まずはこのTop16 Manager2.3のようにインプットがON時の状態をリアルタイムに検知できるようにと考えています。
発生している問題・エラーメッセージ
提供されているDllをどうやって使ってリアルタイムにインプット信号が検出できるか分からず、まだエラーメッセージを発生させるに至っておりません。
該当のソースコード
まずはインプット信号(in 1)のみをリアルタイムで検出できるよう検討しています。
C#(Form1.cs)
1using System; 2using System.Collections; 3using System.Text; 4using System.Windows.Forms; 5using System.IO; 6using System.Drawing; 7 8namespace Top16_TestWinForm 9{ 10 public partial class Form1 : Form 11 { 12 public Form1() 13 { 14 InitializeComponent(); 15 StartPosition = FormStartPosition.CenterScreen; 16 } 17 18 private void Top16Refresh() 19 { 20 try 21 { 22 //ここからTOP16の制御 23 const int MAX_NO_BOARDS = 124; 24 const int MAX_NAME_LEN = 20; 25 26 //使用しているDllバージョンの表示 27 string outstring1 = "DLL version = " + Top16.dllversion() + "\n"; 28 label4.Text = outstring1; 29 30 // Read the number of boards and names 31 byte[] byBoardNames = new byte[MAX_NO_BOARDS * MAX_NAME_LEN]; 32 Int32 boardsFound = Top16.ListTop16Boards(byBoardNames); 33 String sListOfBoards = Encoding.ASCII.GetString(byBoardNames, 0, MAX_NO_BOARDS * MAX_NAME_LEN); 34 35 //TOP16ボードの枚数表示 36 string outstring2 = Convert.ToString(boardsFound); 37 label6.Text = outstring2; 38 39 // Make a list of all the board names 40 ArrayList sBoardNames = new ArrayList(); 41 for (int i = 0; i < boardsFound; i++) 42 { 43 // List the names of all Top16 boards found, and add them to an ArrayList 44 //TOP16の名前表示 45 sBoardNames.Add(sListOfBoards.Substring(i * MAX_NAME_LEN, MAX_NAME_LEN)); 46 String outstring3 = sBoardNames[i] + "\n"; 47 dataGridView1.Rows[0].Cells[0].Value = outstring3; 48 } 49 50 //画面ロード時に一度インプット状態を検知する 51 for (int i = 0; i < sBoardNames.Count; i++) 52 { 53 UInt64 handle = Top16.OpenBoard(new StringBuilder((String)sBoardNames[i])); 54 if (handle > 0) 55 { 56 // read an analog input まずはインプット1のみ 57 int aInput = Top16.readAnalogInput(handle, 1, (byte)'Z'); 58 59 //いくつかサンプリングし3998以上で未入力状態 60 if (aInput > 3998) 61 { 62 dataGridView1.Rows[0].Cells[1].Style.BackColor = Color.Blue; 63 } 64 65 //Gainの表示 66 String outstring5 = Convert.ToString(aInput); 67 label8.Text = outstring5; 68 69 // close the board 70 // 71 Top16.CloseBoard(handle); 72 } 73 } 74 } 75 catch (Exception ex) 76 { 77 // Display an error if caught 78 79 MessageBox.Show(ex.Message); 80 } 81 } 82 83 private void Form1_Load(object sender, EventArgs e) 84 { 85 //ロード時にインプット信号の状態をとる 86 Top16Refresh(); 87 } 88 89 private void button1_Click(object sender, EventArgs e) 90 { 91 //ボタン操作でインプット状態の更新する 92 Top16Refresh(); 93 } 94 } 95} 96
C#(Top16.cs)
1using System; 2using System.Runtime.InteropServices; 3using System.Text; 4 5namespace Top16_TestWinForm 6{ 7 public class Top16 8 { 9 [DllImport("top16_64.dll")] 10 public static extern Int32 dllversion(); 11 12 [DllImport("top16_64.dll")] 13 public static extern Int32 ListTop16Boards(byte[] sBoardNames); 14 15 [DllImport("top16_64.dll")] 16 public static extern Int32 SetOutputs(UInt64 Handle, Byte mask, Byte set); 17 18 [DllImport("top16_64.dll")] 19 public static extern Int32 GetInputs(UInt64 Handle); 20 21 [DllImport("top16_64.dll")] 22 public static extern Int32 readAnalogInput(UInt64 Handle, Int16 input, byte gain); 23 24 [DllImport("top16_64.dll")] 25 public static extern UInt64 OpenBoard(StringBuilder boardName); 26 27 [DllImport("top16_64.dll")] 28 public static extern Int32 CloseBoard(UInt64 Handle); 29 } 30}
試したこと
まずは安易に検出部のメソッドTop16Refresh();をWhile文で回していれば検出できるかと考えました。
駄目だったこと
・ループ中は他の操作ができない(ビジー状態?)
・インプットを検出できない
・試してはいませんが、もし仮にループから抜けさせても、再びボタン操作をしないと次のインプットを検出できないのでは。それでは目的と異なる。
それでそもそもDllの使い方を間違っているのではないかと思い、ここ三日間ほどインターネットを検索をしているのですが専門用語が分かっていないのか?期待する説明が見つけられずteratailにたどり着きました。
補足情報(FW/ツールのバージョンなど)
Microsoft Visual Studio Community 2022
Version 17.5.5
VisualStudio.17.Release/17.5.5+33627.172
Microsoft .NET Framework
Version 4.8.09032
回答1件
あなたの回答
tips
プレビュー