2016-04-15 32 views
-1

在我的VB.NET應用程序中,我使用了一個來自.dll的函數,它會給我一個字符串。 當調用該函數時,回調會給出該字符串的長度和地址,而不是字符串本身。來自VB.NET地址的字符串

我嘗試使用此代碼來獲取字符串,但我認爲這是針對VB的經典,而不是爲VB.NET:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Object, ByVal Source As Object, ByVal Length As Long) 
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long 

Private Function pvToString(ByVal lPtr As Long) As String 
    If lPtr <> 0 Then 
    pvToString = String(lstrlenA(lPtr), 0) 
    Call CopyMemory(ByVal pvToString, ByVal lPtr, Len(pvToString)) 
    End If 
End Function 

我得到4個錯誤,我不知道如何擺脫其中:

  1. '。'預期(用於字符串第5行)
  2. 「字符串」是一個類類型,不能用作表達式(對於第5行)
  3. 表達預期的(用於BYVAL第6行)
  4. 表達預期的(對第6行爲ByVal)

對不起,如果我的問題很蠢。我在編程起動器和VB.NET

+0

什麼我可以幫助你:刪除'ByVal'。 –

+0

完整的例子是如何使用這個在這裏:http://www.pinvoke.net/default.aspx/urlmon/CopyMemory.html –

+0

在看了一個VB6文檔後,'String()'函數只是創建一個字符串填充與指定數量的特定字符一起使用。你應該能夠刪除這條線沒有任何問題。 –

回答

-3

看起來你的聲明應該是這樣

Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As String 

,而不是

Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long 

對不起有到Visual Studio沒有訪問權限,現在來測試這個。但看起來這是它出錯的地方。

PS:聲明可能對其他函數也是錯誤的。嘗試刪除ByVal

+0

why -vote?這對你來說可能是更好的答案。 http://stackoverflow.com/questions/3921852/how-to-get-the-string-from-an-address-specified-by-a-long-in-vb – Imran

+0

你可能會得到一個downvote,因爲你是什麼說是不正確的。事實上,它實際上應該是'Integer':http://www.pinvoke.net/default.aspx/kernel32.lstrlen - **另外**,你給他的鏈接幾乎與他使用的代碼完全一樣,意味着它將無法工作。 –

+0

另外,'ByVal'不會使聲明不正確。如果你不使用'ByVal',編譯器會默認添加它。我認爲這兩點解釋了downvote。 –

1

首先關於錯誤:
1和2:改用新的String('',len)。
3和4:刪除callByVal
和所有Long變量和參數必須聲明爲整數期望lstrlen應該被聲明爲IntPtr的。無論如何,你應該忘記一切。如果你有一個指針(IntPtr的),你想將其轉換爲字符串,這取決於你的字符串類型,你可以很容易地使用:
昏暗的myString作爲字符串= System.Runtime.InteropServices.Marshal.PtrToStrXXXX(MyPSZString)

+0

我用你的元帥建議。現在我得到的是中文字符而不是羅馬字符。這很奇怪,因爲源字符串是羅馬字母。:D任何想法? – VBStarter

+0

我用過Marshal.PtrToStrAuto() – VBStarter

+0

'PtrToStrAuto'解決了問題嗎?嘗試BSTR和Uni版本。你能插入你的非託管函數簽名嗎? –