- 題名: C#→VBへの移植でうまくいきません
- 日時: 2011/08/15 14:25:42
- ID: 28890
- この記事の返信元:
- (なし)
- この記事への返信:
- [28891] Re[1]: C#→VBへの移植でうまくいきません2011/08/15 14:52:57
- ツリーを表示
コメント頂き、ありがとうございます。
エラーメッセージですが、
Message="型 'ClientTest.RemoteTranceObject.ClassFileInfo, ClientTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' を読み込めません。"
というのが出てます。
それと、以下、サーバー側のコードです。
よろしくお願いします。
'System.Runtime.Remotingを参照設定する必要があります
Imports System.Runtime.Remoting.Channels.ipc
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting
'Imports RemoteTranceObject
Public Class FormSrever
Dim m_msg As RemoteTranceObject.ClassFileInfo
'フォームロード
Private Sub FormSrever_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'このチャネル生成系は一度通せばいいっぽい
'IPC Channel を作成
Dim servChannel As IpcServerChannel = New IpcServerChannel("processtrancetest")
'IpcServerChannel servChannel = new IpcServerChannel("processtrancetest");
'リモートオブジェクトを登録
ChannelServices.RegisterChannel(servChannel, True)
'ChannelServices.RegisterChannel(servChannel, true);
'ChannelのURIを表示
Label1.Text = servChannel.GetChannelUri()
'label1.Text = servChannel.GetChannelUri();
'イベントを登録
m_msg = New RemoteTranceObject.ClassFileInfo()
AddHandler m_msg.OnTrance, AddressOf m_msg_OnTrance
RemotingServices.Marshal(m_msg, "message", GetType(RemoteTranceObject.ClassFileInfo))
'm_msg = new ClassFileInfo();
'm_msg.OnTrance += new ClassFileInfo.CallEventHandler(m_msg_OnTrance);
'RemotingServices.Marshal(m_msg, "message", typeof(ClassFileInfo));
End Sub
'クライアントから転送されてきた情報をリストボックスに表示
Private Sub m_msg_OnTrance(ByVal e As RemoteTranceObject.ClassFileInfo.ClassFileInfoEventArg)
Dim st As String
Select Case e.Mode
Case 1
st = "モード1"
Case 2
st = "モード2"
Case 3
st = "モード3"
Case Else
st = "???"
End Select
ListBox1.Items.Add(st + " , " + e.FileName)
End Sub
End Class
Namespace RemoteTranceObject '共有オブジェクト(サーバー/クライアントで全く同一内容で定義してください)
Public Class ClassFileInfo
Inherits MarshalByRefObject
Public Class ClassFileInfoEventArg
Inherits EventArgs '情報を引き渡すイベント引数クラス
Private m_mode As Integer = 0 'モード
Private m_FileName As String = "" '文字列
Property Mode() As Integer
Get
Return m_mode
End Get
Set(ByVal value As Integer)
m_mode = value
End Set
End Property
Property FileName() As String
Get
Return m_FileName
End Get
Set(ByVal value As String)
m_FileName = value
End Set
End Property
Public Sub New(ByVal tmpMode As Integer, ByVal tmpfName As String)
m_mode = tmpMode
m_FileName = tmpfName
End Sub
End Class
Public Delegate Sub CallEventHandler(ByVal e As ClassFileInfoEventArg)
Public Event OnTrance As CallEventHandler
Public Sub DataTrance(ByVal tmpmode As Integer, ByVal tmpfname As String)
RaiseEvent OnTrance(New ClassFileInfoEventArg(tmpmode, tmpfname))
End Sub
End Class
End Namespace
■No28891に返信(Azuleanさんの記事)
> ■No28890に返信(ひで46 さんの記事)
>>System.Runtime.Remoting.RemotingException' の初回例外が mscorlib.dll で発生しました。
>>とメッセージが出てしまいます。どこが悪いのでしょうか。
>
> RemotingException とともに何かメッセージが出ていませんでしたか?
> (たとえば、「AA 型がシリアライズ可能とマークされていません」といったもの)
>
> そのメッセージがないと、エラー要因がわかりづらいと思います。
> あと、サーバー側は今どうなっているんですか?
回答ありがとうございます。 ご指摘の通り、ソルーションの中にクライアント用とサーバー用の2つのプロジェクトが 入ってます。 各プロジェクトのプロパティを開いてアプリケーションタブのルート名前空間というところを空欄にしてリビルドしたら見事動作しました。 > こういった方法が面倒なのであれば、共有するクラスを別のプロジェクトに切り出し、 これについては「吟遊詩人の戯言」サイトでも 「この部分だけ,クラスDLLにして,参照設定しちゃうほうが,あとあと管理が楽かも?」 とのコメントが書いてありました。 今回は新しいことを知ることが出来てよかったです。 ■No28893に返信(Azuleanさんの記事) > ■No28892に返信(ひで46 さんの記事) >>エラーメッセージですが、 >> Message="型 'ClientTest.RemoteTranceObject.ClassFileInfo, ClientTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' を読み込めません。" >>というのが出てます。 > > これは、VB.NET 特有の事情が絡んでいます。 > VB.NET のプロジェクトではプロジェクトのプロパティにルート名前空間というものが指定できるようになっており、ここに何か入っているとそのプロジェクトの中のクラスなどはその名前空間以下に属するようになります。 > ここで "ClientTest.RemoteTranceObject.ClassFileInfo" と最初に "ClientTest" とついているのはルート名前空間のせいでしょう。 > そして、サーバー側は "ServerTest.RemoteTranceObject.ClassFileInfo" となっていると推測され、名前空間を合わせた型名で一致する型が見つからないから例外が発生しているのでしょう。 > > C# でのサンプルではルート名前空間という概念がないので、名前空間を含めた型名を一致させる書き方だったのでしょう。 > VB.NET で合わせるためにはプロジェクトのプロパティからルート名前空間を空欄にしてください。なお、フォームなどのほかのクラスは必要に応じて名前空間を調整してください。 > > > こういった方法が面倒なのであれば、共有するクラスを別のプロジェクトに切り出し、そのプロジェクトをサーバー側、クライアント側が両方とも参照する形にすれば、こういう無理矢理なやり方(厳密に同じ型といえないのにそう見せかけているやり方)からは脱することができると考えられます。
分類:[.NET]
いつも参考にさせて頂いております。 自PC内でのプロセス間通信をやりたくてC#で記述されたサンプルをネット上で見つけました。 「吟遊詩人の戯言」さんのサイトです。 http://gurizuri0505.halfmoon.jp/develop/csharp/processmessage これをVBで書き換えようとしてますが、うまくいきません。 以下はクライアント側のソースですが、実行して「送信」クリックすると System.Runtime.Remoting.RemotingException' の初回例外が mscorlib.dll で発生しました。 とメッセージが出てしまいます。どこが悪いのでしょうか。 'System.Runtime.Remotingを参照設定する必要があります Imports System.Runtime.Remoting.Channels.ipc Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting 'Imports RemoteTranceObject Public Class FormClient Private m_mode As Integer = 0 Private m_msg As RemoteTranceObject.ClassFileInfo = Nothing Public Sub New() ' この呼び出しは、Windows フォーム デザイナで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 m_mode = 1 End Sub Private Sub FormClient_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'IPC Channel を作成 Dim clientChannel As IpcClientChannel = New IpcClientChannel() 'IpcClientChannel clientChannel = new IpcClientChannel(); 'リモートオブジェクトを登録 ChannelServices.RegisterChannel(clientChannel, True) 'ChannelServices.RegisterChannel(clientChannel, true); 'オブジェクトを作成 m_msg = Activator.GetObject(GetType(RemoteTranceObject.ClassFileInfo), "ipc://processtrancetest/message") 'm_msg = (ClassFileInfo)Activator.GetObject(typeof(ClassFileInfo), "ipc://processtrancetest/message"); End Sub 'ラジオボタンでモードを設定 Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged, RadioButton3.CheckedChanged, RadioButton2.CheckedChanged Dim st As String If sender.tag = Nothing Then Exit Sub End If st = sender.Tag m_mode = Integer.Parse(st) 'string st = (sender as RadioButton).Tag as string; 'm_mode = int.Parse(st); End Sub 'ボタンを押すたびに,モードと入力文字をサーバ側へ送信 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim st As String = TextBox1.Text If st = "" Then st = "空文字" End If m_msg.DataTrance(m_mode, st) 'サーバーへ伝送 'string st = textBox1.Text; 'if (st == "") '{ ' st = "空文字"; '} 'm_msg.DataTrance(m_mode, st); //サーバーへ伝送 End Sub End Class Namespace RemoteTranceObject '共有オブジェクト(サーバー/クライアントで全く同一内容で定義してください) Public Class ClassFileInfo Inherits MarshalByRefObject Public Class ClassFileInfoEventArg Inherits EventArgs '情報を引き渡すイベント引数クラス Private m_mode As Integer = 0 'モード Private m_FileName As String = "" '文字列 Property Mode() As Integer Get Return m_mode End Get Set(ByVal value As Integer) m_mode = value End Set End Property Property FileName() As String Get Return m_FileName End Get Set(ByVal value As String) m_FileName = value End Set End Property Public Sub New(ByVal tmpMode As Integer, ByVal tmpfName As String) m_mode = tmpMode m_FileName = tmpfName End Sub End Class Public Delegate Sub CallEventHandler(ByVal e As ClassFileInfoEventArg) Public Event OnTrance As CallEventHandler Public Sub DataTrance(ByVal tmpmode As Integer, ByVal tmpfname As String) RaiseEvent OnTrance(New ClassFileInfoEventArg(tmpmode, tmpfname)) End Sub End Class End Namespace