我一整天都在關注這個問題,並且我無法理解關於此的各種(有時是衝突的)文檔。爲了增加混淆,在白天的某個時候,這確實(有點)工作 - 即沒有發出訪問違規錯誤。但是管道另一端的數據是無稽之談,所以我懷疑這只是偶然發生的。在命名管道上從visual basic .net 2010調用WriteFile的錯誤
我有一個vb.net程序(使用.net 3.0所以不支持System.IO.NamedPipes :()它創建一個命名管道,並等待另一個應用程序來連接和發送一些數據作爲'ack' ,然後我想讓vb程序發送收到的消息的總長度,我可以創建管道,等待連接並接收消息,但是它會嘗試使用WriteFile
發送'ack'。我使用WriteFile
(當前)的定義是基於相應ReadFile
,這似乎很好地工作:
Declare Function ReadFile Lib "kernel32" (_
ByVal hFile As Integer, _
ByRef lpBuffer As Byte, _
ByVal nNumberOfBytesToRead As Integer, _
ByRef lpNumberOfBytesRead As Integer, _
ByVal lpOverlapped As Integer) _
As Integer
Declare Function WriteFile Lib "kernel32" (_
ByVal hFile As Long, _
ByRef lpBuffer As Byte, _
ByVal nNumberOfBytesToWrite As Integer, _
ByRef lpNumberOfBytesWritten As Integer, _
ByVal lpOverlapped As Integer) _
As Integer
的精簡代碼(錯誤檢查和調試印刷去除)看起來像這樣:
Dim openMode = PIPE_ACCESS_DUPLEX Or FILE_FLAG_FIRST_PIPE_INSTANCE
Dim pipeMode = PIPE_WAIT Or PIPE_TYPE_MESSAGE Or PIPE_READMODE_MESSAGE
Dim res ' Result of dll calls
pipeN2Q = CreateNamedPipe("\\.\pipe\N2Q", openMode, pipeMode, 10, 1024, 1024, 2000, IntPtr.Zero)
res = ConnectNamedPipe(pipeN2Q, 0)
Dim rxCount As Integer = 0 ' To hold the number of bytes received
Dim txCount As Integer = 0 ' To hold the number of bytes sent
Dim txReq As Integer = 2 ' To hold the number of bytes we're going to ask to be sent during the 'ack'
Dim dataIn(256) As Byte
res = ReadFile(pipeN2Q, dataIn(0), 256, rxCount, Nothing)
Dim recvBuffer As String = System.Text.Encoding.ASCII.GetString(dataIn, 0, rxCount)
Dim dataOut(2) As Byte
dataOut(0) = 42
dataOut(1) = 43
res = WriteFile(pipeN2Q, dataOut(0), txReq, txCount, Nothing)
一旦代碼獲取到WriteFile
,它拋出一個AccessViolationException - 「嘗試讀取或寫入受保護的內存。」我猜想這是抱怨dataOut
參數,但它沒有給出進一步的細節。事情到目前爲止,我已經試過包括:
- 改變的
WriteFile
的聲明,使lpBuffer
聲明:使用Marshal.AllocHGlobal(txReq)
ByVal lpBuffer as IntPtr
- 清分數據出,並使用
Marshal.WriteInt16()
- 分配的
dataOut
大的緩衝初始化(1024個字節)並將它們初始化爲零
要清楚,來自其他應用程序的消息可以完美接收,並且recvBuffer
與發送的字符串完全相同。我無法說服WriteFile進行合作(除了一次,也許偶然,我無法重複)。我希望這只是變量的聲明或初始化 - 任何線索?
您的標註聲明不好。使用pinvoke.net網站找到好的。 –
謝謝 - pinvoke.net是我一直在提到的網站之一 - 雖然它有3個不同的WriteFile簽名,ReadFile的返回類型顯示爲SafeFileHandle,而在MSDN上顯示爲布爾值。所以我沒有真正相信它......但是,使用StringBuilder作爲傳輸緩衝區類型的版本終於允許我從雙方發送乾淨的數據,所以感謝指針。 – dsl101