下記のサイトを参考に、アプリ間通信をしたいのですができません。
http://gurizuri0505.halfmoon.jp/develop/csharp/processmessage
エラー内容は以下です。
クライアント側であるTestClientの「 m_msg.DataTrance(m_mode, st); 」の部分です。
System.NullReferenceException: 'オブジェクト参照がオブジェクト インスタンスに設定されていません。'
m_msg が null でした。
オブジェクトにイベントは設定しております。
実行する際は、
ご教授よろしくお願いします。
C#
1 2//TestClient 3 4using System; 5using System.Collections.Generic; 6using System.ComponentModel; 7using System.Data; 8using System.Drawing; 9using System.Linq; 10using System.Text; 11using System.Threading.Tasks; 12using System.Windows.Forms; 13 14using System.Runtime.Remoting.Channels.Ipc; 15using System.Runtime.Remoting.Channels; 16using System.Runtime.Remoting; 17using RemoteTranceObject; 18 19 20namespace WindowsFormsApp1 21{ 22 public partial class Form1 : Form 23 { 24 private int m_mode; 25 private ClassFileInfo m_msg = null; 26 //コンストラクタ 27 public Form1() 28 { 29 InitializeComponent(); 30 m_mode = 1; 31 } 32 33 //フォームロード 34 private void Form1_Load(object sender, EventArgs e) 35 { 36 //このチャネル生成系は一度通せばいいっぽい 37 38 // IPC Channel を作成 39 IpcClientChannel clientChannel = new IpcClientChannel(); 40 // リモートオブジェクトを登録 41 ChannelServices.RegisterChannel(clientChannel, true); 42 // オブジェクトを作成 43 m_msg = (ClassFileInfo)Activator.GetObject(typeof(ClassFileInfo), "ipc://processtrancetest/message"); 44 } 45 46 //ラジオボタンでモードを設定 47 private void rdbClick(object sender, EventArgs e) 48 { 49 50 string st = (sender as RadioButton).Tag as string; 51 m_mode = int.Parse(st); 52 53 } 54 55 //ボタンを押すたびに,モードと入力文字をサーバ側へ送信 56 private void button1_Click(object sender, EventArgs e) 57 { 58 string st = textBox1.Text; 59 if (st == "") 60 { 61 st = "空文字"; 62 } 63 64** m_msg.DataTrance(m_mode, st); //サーバーへ伝送** 65 } 66 67 } 68} 69 70 71 72namespace RemoteTranceObject //共有オブジェクト(サーバー/クライアントで全く同一内容で定義してください) 73{ 74 public class ClassFileInfo : MarshalByRefObject 75 { 76 public class ClassFileInfoEventArg : EventArgs //情報を引き渡すイベント引数クラス 77 { 78 private int m_mode = 0; //モード 79 private string m_FileName = ""; //文字列 80 public int Mode { get { return m_mode; } set { m_mode = value; } } 81 public string FileName { get { return m_FileName; } set { m_FileName = value; } } 82 public ClassFileInfoEventArg(int tmpMode, string tmpfName) 83 { 84 m_mode = tmpMode; 85 m_FileName = tmpfName; 86 } 87 } 88 89 public delegate void CallEventHandler(ClassFileInfoEventArg e); 90 public event CallEventHandler OnTrance; 91 public void DataTrance(int tmpmode, string tmpfname) 92 { 93 if (OnTrance != null) 94 { 95 OnTrance(new ClassFileInfoEventArg(tmpmode, tmpfname)); 96 } 97 } 98 99 } 100}
C#
1 2//TestServer 3 4using System; 5using System.Collections.Generic; 6using System.ComponentModel; 7using System.Data; 8using System.Drawing; 9using System.Linq; 10using System.Text; 11using System.Threading.Tasks; 12using System.Windows.Forms; 13 14using System.Runtime.Remoting.Channels.Ipc; 15using System.Runtime.Remoting.Channels; 16using System.Runtime.Remoting; 17using RemoteTranceObject; 18 19 20namespace WindowsFormsApp1 21{ 22 public partial class Form1 : Form 23 { 24 private ClassFileInfo m_msg; 25 //コンストラクタ 26 public Form1() 27 { 28 InitializeComponent(); 29 } 30 31 //フォームロード 32 private void Form1_Load(object sender, EventArgs e) 33 { 34 //このチャネル生成系は一度通せばいいっぽい 35 36 // IPC Channelを作成 37 IpcServerChannel servChannel = new IpcServerChannel("processtrancetest"); 38 // リモートオブジェクトを登録 39 ChannelServices.RegisterChannel(servChannel, true); 40 //// ChannelのURIを表示 41 label1.Text = servChannel.GetChannelUri(); 42 43 // イベントを登録 44 m_msg = new ClassFileInfo(); 45 46 m_msg.OnTrance += new ClassFileInfo.CallEventHandler(m_msg_OnTrance); 47 RemotingServices.Marshal(m_msg, "message", typeof(ClassFileInfo)); 48 } 49 50 //クライアントから転送されてきた情報をリストボックスに表示 51 void m_msg_OnTrance(ClassFileInfo.ClassFileInfoEventArg e) 52 { 53 string st; 54 switch (e.Mode) 55 { 56 case 1: 57 st = "モード1"; 58 break; 59 case 2: 60 st = "モード2"; 61 break; 62 case 3: 63 st = "モード3"; 64 break; 65 default: 66 st = "???"; 67 break; 68 } 69 70 71 listBox1.Items.Add(st + " , " + e.FileName); 72 } 73 } 74} 75 76 77namespace RemoteTranceObject //共有オブジェクト(サーバー/クライアントで全く同一内容で定義してください) 78{ 79 public class ClassFileInfo : MarshalByRefObject 80 { 81 public class ClassFileInfoEventArg : EventArgs //情報を引き渡すイベント引数クラス 82 { 83 private int m_mode = 0; //モード 84 private string m_FileName = ""; //文字列 85 public int Mode { get { return m_mode; } set { m_mode = value; } } 86 public string FileName { get { return m_FileName; } set { m_FileName = value; } } 87 public ClassFileInfoEventArg(int tmpMode, string tmpfName) 88 { 89 m_mode = tmpMode; 90 m_FileName = tmpfName; 91 } 92 } 93 94 public delegate void CallEventHandler(ClassFileInfoEventArg e); 95 public event CallEventHandler OnTrance; 96 public void DataTrance(int tmpmode, string tmpfname) 97 { 98 if (OnTrance != null) 99 { 100 OnTrance(new ClassFileInfoEventArg(tmpmode, tmpfname)); 101 } 102 } 103 104 } 105}
RemoteTranceObject.ClassFileInfo は同じようなコードを2回書くのではなく、同じコードを参照してください。
hihijijiさん、ありがとうございます。
調べてみたのですが、知識不足でhihijijiさんの仰っている事が理解できません…。
「同じようなコードを2回書くのではなく」というのは、クライアント側とサーバ側の両方に書くのではなく、ということでしょうか?
後同じコードを参照するとは、なんて検索したら、方法が出てくるでしょうか。
無知で恐縮ですが、よろしくお願いします。
色々やり方はありますが、RemoteTranceObjectをクラスライブラリとして独立したプロジェクトにするのが簡単かな?
RemoteTranceObjectをクラスライブラリとして独立したプロジェクトにしてみましたが、エラー内容は変わらなかったです。。。
m_msg = (ClassFileInfo)Activator.GetObject(typeof(ClassFileInfo), "ipc://processtrancetest/message");
で思った通りのオブジェクトが取得できているか確認しましたか?
その行から m_msg = null となっていますね
サーバ側を先に立ち上げてますか?
同ソリューションにプロジェクトを作成したため、おそらく同時にあがっているかと思います。
サーバ側が立ち上がったことを確認してから、クライアント側を立ち上げてください。
朝来て試してみたら、解決しました!!
本当にありがとうございました!
回答1件
あなたの回答
tips
プレビュー