0

Windowsメッセージを介して通信しているC#の2つのアプリケーションがありますApp1:App2にメッセージを送信します

string msg=UserName+","+UserAge;

byte[] sarr =System.Text.Encoding.Default.GetBytes(msg);//

int len = sarr.Length;

COPYDATASTRUCT cds;

cds.dwData = (IntPtr)100;

cds.lpData = msg;

cds.cbData = len + 1;

result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);

App2:App1からメッセージを受信します

COPYDATASTRUCT sentPara = new COPYDATASTRUCT();
Type mytype = sentPara.GetType();
sentPara = (COPYDATASTRUCT)message.GetLParam(mytype);
string[] parameters = sentPara.lpData.Split(',');

問題: ユーザー名がロシア語で、App2で受け取ったときに疑問符「???????」が表示されました。これはバイト配列のエンコーディングにあると思いますが、解決方法がありません。

4

2 に答える 2

2

2番目のコードに行を追加します。

    COPYDATASTRUCT sentPara = new COPYDATASTRUCT();
Type mytype = sentPara.GetType();
sentPara = (COPYDATASTRUCT)message.GetLParam(mytype);
var parametersDecoded = System.Text.Encoding.Default.GetString(sentPara.lpData);
string[] parameters = parametersDecoded.Split(',');
于 2013-03-19T10:03:01.873 に答える
2

2つのアプリケーションは2つの別々のプロセスとして実行されていますか?

stringその場合、他のプロセスのアドレス空間では無効になる内部ポインタが含まれているため、直接送信することはできません。STRINGクラスに何が含まれているのかわかりません-非表示になっています。したがって、「確かに含まれている」ではなく、それらを含んでいる可能性があります。

(C#/。Netでは確かに含まれていますが)。

順調に始めました。その文字列の内容を生のバイト配列にパックし、データのみが含まれ、ポインタが含まれていないことを自分で保証してから、生の配列を2番目のプロセスに送信する必要があります。

問題の核心は、構造のP/Invoke定義が間違っていることですCOPYDATA。はタイプでlpVoidはなくstring、タイプbyte[]または。である必要がありIntPtrます。タイプをに変更するbyte[]と、コンパイラはすぐに「=msg」と「.Split」が無効であることを示します。

現在のSENDINGコードには、エラーが1つだけ含まれていることに注意してください。指定した「データ長」は配列の長さです(正しい)が、配列「sarr」ではなく「msg」を渡します。lpVoidタイプを修正した後、フィールドをに設定するだけsarrです。

次に、受信側で、COPYDATAを取得し、そこから取得し、lpVoidそれをaとして使用して、メソッドbyte[]に渡す必要があります。これは、 zaitsmanが提示Encoding.GetString()したものと同様 です。

于 2013-03-19T10:19:11.953 に答える