2016-04-15 34 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版本。你能插入你的非托管函数签名吗? –