.NET Tips
RS-232C経由でシリアル通信をする
- まず最初に MSComm コントロールへの参照をプロジェクトに追加します。
- メニューから「プロジェクト」→「参照の追加」を開く
- 「COM」タブから「Microsoft Comm Control 6.0」 (ファイル名は MSComm32.ocx) をダブルクリック
- ※VB6がインストールされている,または,MSComm32.ocxがregsvr32によって登録されている必要があります
- 「OK」 ボタンをクリック
public class RS232C_Receiver
{
// MSComm(シリアル通信用) オブジェクト
private MSCommLib.MSComm m_comm = new MSCommLib.MSCommClass();
// コンストラクタ
public RS232C_Receiver()
{
InitComPort(1); // COMポートオープン
}
// COM ポートの設定&オープン
public void InitComPort(short portNum)
{
// ポート番号の指定
m_comm.CommPort = portNum;
// 通信条件(baudrate,パリティの有無,length,StopBit)
m_comm.Settings = "9600,N,8,1";
// テキストモードで受信(バイナリモードのときは,「.comInputModeBinary」を指定する)
m_comm.InputMode = MSCommLib.InputModeConstants.comInputModeText;
// ハンドシェイクなし
m_comm.Handshaking = MSCommLib.HandshakeConstants.comNone;
// 4 バイト受信するごとに OnComm() が呼び出される
m_comm.RThreshold = 4;
// Input で受信バッファから全バイト取得
m_comm.InputLen = 0;
// イベントハンドラを設定
m_comm.OnComm += new MSCommLib.DMSCommEvents_OnCommEventHandler(this.OnComm);
try
{
// ポートオープン
m_comm.PortOpen = true;
}
catch (Exception exp)
{
System.Windows.Forms.MessageBox.Show("ポート" + portNum + "のオープンに失敗:" + exp.Message);
}
}
// MSComm のイベントハンドラ(受信時に呼ばれる)
private void OnComm()
{
if (m_comm.InBufferCount > 0)
{
// Input プロパティにデータが格納される
OnCommReceive((byte[]) m_comm.Input);
}
}
// COM ポートからの受信
private void OnCommReceive(string input)
//private void OnCommReceive(byte[] input) // バイナリモードのときはこちら
{
// デバッグ出力
System.Diagnostics.Debug.WriteLine("OnCommReceive: " + input);
}
}
バイナリ形式でファイルに書き込む
string filename = "hoge.dat";
System.IO.BinaryWriter writer = new System.IO.BinaryWriter(
new System.IO.FileStream(filename, System.IO.FileMode.Create));
// FileMode.Create:常に新しいファイルを作成する.ファイルが既に存在する場合は古いのが削除される.
VS.NETでデバッグ・メッセージを出力する
デバッグ出力をIDE上の出力ウィンドウに表示するには,
System.Diagnostics.Debug.WriteLine("hogehoge");
現在の日時を得る
System.DateTime.Nowを使います.
// 「年月日_時分秒」の形式の文字列を作成
string filename = System.DateTime.Now.ToString("yyyyMMdd_hhmmss");
// 「年/月/日 時:分:秒」の形式の文字列を作成
string dateAndHour = System.DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss");
共用体(union)を使う
C++で以下のような構造体+共用体を
struct Union1
{
union
{
long a;
struct
{
char b0;
char b1;
char b2;
char b3;
}
}
上記の例では,メンバ a と,メンバ b0 〜 b3 は同じメモリ領域を共有している.これを C# で実現するには,FieldOffset を利用すればよい.
[StructLayout(LayoutKind.Explicit)]
struct Union1
{
[FieldOffset(0)] public int a;
[FieldOffset(0)] public byte b0;
[FieldOffset(1)] public byte b1;
[FieldOffset(2)] public byte b2;
[FieldOffset(3)] public byte b3;
}
列挙型を使う
public enum DaysOfTheWeek
{
mydaySaturday = 1,
mydaySunday = 2,
mydayMonday = 3,
mydayTuesday = 4,
mydayWednesday = 5,
mydayThursday = 6,
mydayFriday = 7
}
// データ型をint以外に変えることもできます
// C#
enum AccountType : byte
{
myAccountSavings = 1,
myAccountChecking = 2
}
プリミティブな値型の変数を関数の引数として参照渡しする
関数の中で複数の値を書き換えて,それを関数から戻ってきてから使いたいことがあります.C++では,ポインタや参照私をしてやればよいですが,C#でもintや構造体の参照渡しができます.
関数呼び出しと関数の引数に「ref」をつけます.
static void Main()
{
int a = 100;
System.Console.Write("{0} → ", a);
Test(ref a);
System.Console.Write("{0}\n", a);
}
static void Test(ref int value)
{
value = 10; // メソッド内で値を書き換えることができる
}
C# における構造体とクラスの違い
- 構造体はプリミティブな変数宣言と同じように実体化するのに対して,クラスは new で実体化する.(構造体を new して実体化することもできる)
- 構造体は値型であり,クラスのインスタンスは参照型である
忘れがちな演算子
is演算子
- 1 is int = True
- 1.0 is int = False
論理演算子(XOR)
- a ^ b
as演算子
キャストと似たような感じobject instance1 = new Class3(); Console.WriteLine(instance1); Class2 instance2 = instance1 as Class2;
演算子の定義
クラスごとに演算子の挙動を定義できる
class Class2
{
public string str;
public Class2( string s ) { str = s; }
public static Class2 operator -(Class2 x)
{
return new Class2( "-" + x.str );
}
public static Class2 operator +(Class2 x, Class2 y)
{
return new Class2( x.str + "+" + y.str );
}
}
XMLファイルを読み込む
Imports System.xml ' XMLの作成・操作用ライブラリ
Private Sub LoadXml()
' 読み込むXMLファイル名(アプリケーションと同じディレクトリにあるtest.xml)
Dim filename As String = Application.StartupPath + "\test.xml"
' XMLドキュメントの作成
Dim xmlDoc As New XmlDocument
' XMLファイルの読み込み
xmlDoc.Load(filename)
' 指定した要素名のデータを検索する
Dim nodeList As XmlNodeList = xmlDoc.SelectNodes("/user/name")
If nodeList Is Nothing Then ' なければ
Exit Sub
End If
' 要素毎に処理する
Dim node As XmlNode
For Each node In nodeList
' 表示
MessageBox.Show(node.InnerText + node.Attributes.GetNamedItem("age").Value)
Next
End Sub
XMLファイルに保存(出力)する
Public Sub SaveXml()
''' XMLドキュメントとして保存する
' XML出力用オブジェクト
Dim doc As New Xml.XmlTextWriter(m_path, System.Text.Encoding.UTF8)
doc.Formatting = Xml.Formatting.Indented
doc.WriteStartDocument(True)
' ルートエレメントの書き込み
doc.WriteStartElement("UserList")
' users1要素を書き込む
doc.WriteComment("users1")
doc.WriteStartElement("users1")
Dim i As Integer
For i = 0 To m_memoList.Count - 1
doc.WriteStartElement("user")
doc.WriteAttributeString("age", "23")
doc.WriteString("Hogehoge Taro")
doc.WriteEndElement()
Next
doc.WriteEndElement() ' エンドエレメントの書き込み
doc.WriteEndElement()
doc.WriteEndDocument()
doc.Close()
End Function
ASP.NETのプロジェクトを作成したときにエラーが出る
開発環境:Win XP Pro, .NET 2003, .NET Framework 1.1「Webアプリケーションの新規作成」を行うと,下記エラーが発生する.
「指定されたWebサーバでASP.NET Version1.1が実行されていません。 ASP.NET Webアプリケーションまたはサービスを実行することはできなくなります。」解決法: コマンドプロンプトで以下を実行すればよい
"%windir%\Microsoft.NET\Framework\(version)\aspnet_regiis.exe" -ihttp://support.microsoft.com/default.aspx?scid=kb;ja;306005&Product=iisJPN より
外部プロセスの実行(アプリケーションやファイル)
private void button1_Click(object sender, System.EventArgs e)
{
// 電卓(calc.exe)の起動
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName="calc.exe";
proc.Start();
}
private void button2_Click(object sender, System.EventArgs e)
{
// テキストファイルをデフォルトの(関連付けられた)テキストエディタで開く
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName="c:\\home\\hoge.txt";
proc.Start();
}
private void button3_Click(object sender, System.EventArgs e)
{
// InternetExplorerで指定したページを開く
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName="iexplore";
proc.StartInfo.Arguments="http://www.microsoft.com";
proc.Start();
// アプリの終了を待つ
proc.WaitForExit();
MessageBox.Show("アプリが閉じられました");
}
WindowsネイティブのDLLの関数を呼び出す
using System.Runtime.InteropServices;
namespace Hoge
{
public class HogeHoge
{
[DllImport("user32.dll")]
public static extern System.IntPtr SendMessage(
System.IntPtr hWnd, // 送信先ウィンドウのハンドル
System.UInt32 Msg, // メッセージ
System.IntPtr wParam, // メッセージの最初のパラメータ
System.IntPtr lParam // メッセージの 2 番目のパラメータ
);
private void DoHoge()
{
// WM_COMMAND, 0, 0)
SendMessage(hogehoge.Handle, 0x0111, (IntPtr)0x0, (IntPtr)0x0);
}
}
}
カレントディレクトリを取得する(得る)
// カレントディレクトリの取得
System.IO.Directory.GetCurrentDirectory()
// カレントディレクトリの設定
System.IO.Directory.SetCurrentDirectory("C:/hoge")
メッセージボックスの表示
using System.Windows.Forms;
MessageBox.Show("めっせーじ", "たいとる");
.NETのアプリケーションを高速に動作させる.
.NETのアプリケーションは,中間言語MSILの形になっているために,ネイティブコードのアプリケーションよりも動作が遅くなります.
ただJITコンパイラを使用するため,2回目以降は動作が速くなります.
しかし,起動時はやはり遅いのが問題となります.
これを解決する方法として,
ngen.exe(ネイティブ・イメージ・ジェネレータ)
を利用するという手があります.
これを実行しておくと,
JITコンパイルしたキャッシュをアセンブリに組み込んで,
実行が早くなります.
ただ,PCの環境によってJITコンパイルの結果が変わってくるので,
配布する側の立場としては,インストーラなどに組み込む形態がよいそうです.
参考: http://www.atmarkit.co.jp/fdotnet/vbcheer/vbcheer08/vbcheer08.html
作成日: 2005年10月25日22時56日33秒
![[トップページ]](../lib/img//top.gif)
![[一覧]](../lib/img//list.gif)
![[検索]](../lib/img//search.gif)
![[ヘルプ]](../lib/img//help.gif)
![[ログイン]](../lib/img//login.gif)