2013-03-30 24 views
3

我想從一個VB 2010應用程序發送結構化數據到現有的庫,該庫需要將字符串轉換爲字節數組。我在將數據作爲字節數組發送時遇到問題 - 我可以將應該轉換爲字節的純字符串發送到我編寫的測試程序。VB 2010發送消息:發送二進制數據到另一個應用程序

這是兩個應用程序。首先監聽器進程:

Imports System.Runtime.InteropServices 
Imports System.Collections.Generic 

Public Class frmMain 

<StructLayout(LayoutKind.Sequential)> _ 
Private Structure CopyData 
    Public dwData As IntPtr 
    Public cbData As Integer 
    Public lpData As String 
End Structure 

Private Declare Auto Function SendMessage Lib "user32" _ 
(ByVal hWnd As IntPtr, _ 
    ByVal Msg As Integer, _ 
    ByVal wParam As IntPtr, _ 
    ByRef lParam As CopyData) As Boolean 

Private Declare Auto Function FindWindow Lib "user32" _ 
(ByVal lpClassName As String, _ 
    ByVal lpWindowName As String) As IntPtr 

Private Const WM_COPYDATA As Integer = &H4A 

Private Sub cmdSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSend.Click 


    Dim ClientWindow As IntPtr 
    Dim a() As System.Diagnostics.Process = System.Diagnostics.Process.GetProcesses 

    For Each p In a 
     Console.WriteLine(p.ProcessName) 
     If p.ProcessName = "Listener" Then 
      ClientWindow = p.MainWindowHandle 
      Exit For 
     End If 
    Next 


    ' make sure we found an active client window 
    If Not ClientWindow.Equals(IntPtr.Zero) Then 

     ' if there is text to send 
     If txtText.Text.Length > 0 Then 
      Dim message As String = txtText.Text 
      Dim data As CopyData 

      ' set up the data... 
      data.lpData = message 
      data.cbData = message.Length * Marshal.SystemDefaultCharSize 

      ' send the data 
      frmMain.SendMessage(ClientWindow, frmMain.WM_COPYDATA, Me.Handle, data) 

     End If 
    Else 
     MsgBox("Could Not Find Active Client Window.") 
    End If 
End Sub 

Private Function UnicodeStringToBytes(
ByVal str As String) As Byte() 

    Return System.Text.Encoding.Unicode.GetBytes(str) 
End Function 

End Class 

這一切工作,但如果我改變「公共的lpData作爲字符串」到「公共的lpData爲字節()」中:

Imports System.Runtime.InteropServices 
Public Class frmTest 

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 
    If m.Msg = frmTest.WM_COPYDATA Then 
     Dim data As CopyData 
     Dim message As String 

     ' get the data... 
     data = CType(m.GetLParam(GetType(CopyData)), CopyData) 

     message = data.lpData 
     ' add the message 
     txtTest.Text = message 

     ' let them know we processed the message... 
     m.Result = New IntPtr(1) 
    Else 
     MyBase.WndProc(m) 
    End If 
End Sub 

Private Function UnicodeBytesToString(ByVal bytes() As Byte) As String 

    Return System.Text.Encoding.Unicode.GetString(bytes) 
End Function 

Private Const WM_COPYDATA As Integer = &H4A 

<StructLayout(LayoutKind.Sequential)> _ 
Private Structure CopyData 
    Public dwData As IntPtr 
    Public cbData As Integer 
    Public lpData As String 
End Structure 
End Class 

其次,發送的數據處理然後在偵聽器進程中將'data.lpData = message'修改爲'data.lpData = UnicodeStringToBytes(message)'並將'message = data.lpData'修改爲'message = UnicodeBytesToString(data.lpData)'崩潰。

如何發送字符串作爲字節數組從發送方發送到偵聽器,以便偵聽器可以將其解碼回字符串?

我意識到將字符串作爲字符串發送會更容易,但現有的庫需要它作爲字節數組,所以我試圖讓我的發件人對這個測試偵聽器工作,我可以看到發生了什麼。

在此先感謝!

+0

感謝您的答覆 - 我沒那麼熟悉VB,我所做的更改接收應用程序,但我不確定您在發送應用程序中的含義。 –

回答

2

結構中的變長陣列總是很痛苦。

在兩個申請中聲明lpDataIntPtr

然後在發送應用程序:

' set up the data... 
Dim string_bytes = UnicodeStringToBytes(message) 

Dim pinned = GCHandle.Alloc(string_bytes, GCHandleType.Pinned) 
Try 
    data.dwData = New IntPtr(message.Length) 
    data.cbData = string_bytes.Length 
    data.lpData = pinned.AddrOfPinnedObject() 

    ' send the data 
    frmMain.SendMessage(ClientWindow, frmMain.WM_COPYDATA, Me.Handle, data) 
Finally 
    If pinned.IsAllocated Then pinned.Free() 
End Try 

在接收應用程序:

' get the data... 
data = CType(m.GetLParam(GetType(CopyData)), CopyData) 

Dim message(0 To data.cbData - 1) As Byte 
Marshal.Copy(data.lpData, message, 0, data.cbData) 

' add the message 
txtTest.Text = UnicodeBytesToString(message) 
+0

輝煌,謝謝你的工作完美。現在,讓我的頭在你做的事情上:-) –

相關問題