以下元帅代码几乎可行 [英] The following Marshal code almost works

查看:53
本文介绍了以下元帅代码几乎可行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下几乎可以正常工作。

问题是Marshal.PtrToStringAuto似乎终止于第一个null

所以我没有得到完整的字符串。 />

有关如何解决这个问题的建议吗?

或者如何改进代码?


谢谢


PS我添加了+1,因为据我了解GetLogicalDriveStrings doc

,最后将为Unicode提供一个不计数的null。同意?


Dim lDrives As String

Dim lLenOflDrives As Integer

Dim lPointerToMemory as IntPtr

lLenOflDrives = Kernel.GetLogicalDriveStrings(0,Nothing)

Dim lDrivesSB作为新的StringBuilder(lLenOflDrives + 1)

lDrivesSB.Insert(0,ChrW(33),lLenOflDrives + 1 )

lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)

''获取dirves列表。返回一个:\< null> c:\< null>< null>

如果Kernel.GetLogicalDriveStrings(lLenOflDrives,lPointerToMemory)那么

''会如果宣布了GetLogicalDriveStrings则需要使用PtrToStringAnsi

CharSet.Ansi

lDrives = Marshal.PtrToStringAuto(lPointerToMemory,lLenOflDrives + 1)''文字

to first null,例如a:\

Marshal.FreeHGlobal(lPointerToMemory)

''查看aDrive是否在列表中

DriveExists = InStr(1,lDrives,drive,CompareMethod.Text)

结束如果

The following almost works.
The problem is Marshal.PtrToStringAuto seems to terminate at the first null
so I don''t get the full string.

Any suggestions on how to fix this?
Or how to improve the code?

Thanks

PS I added the +1 because as I understand the GetLogicalDriveStrings doc
there will be an uncounted null at the end for Unicode. Agree?

Dim lDrives As String
Dim lLenOflDrives As Integer
Dim lPointerToMemory As IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0, Nothing)
Dim lDrivesSB As New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0, ChrW(33), lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''Get the list of dirves. Returns a:\<null>c:\<null><null>
If Kernel.GetLogicalDriveStrings(lLenOflDrives, lPointerToMemory) Then
''Would need to use PtrToStringAnsi if GetLogicalDriveStrings were declared
CharSet.Ansi
lDrives = Marshal.PtrToStringAuto(lPointerToMemory, lLenOflDrives + 1) ''Text
to first null, e.g, a:\
Marshal.FreeHGlobal(lPointerToMemory)
''See if aDrive is in the list
DriveExists = InStr(1, lDrives, drive, CompareMethod.Text)
End If

推荐答案

或者如何改进代码?

谢谢

PS我添加了+1,因为据我了解GetLogicalDriveStrings doc
将会有一个不计数的null Unicode的结尾。同意?

Dim lDrives As String
Dim lLenOflDrives as Integer
Dim lPointerToMemory as IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0,Nothing)
Dim lDrivesSB作为New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0,ChrW(33),lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''获取列表迪尔维斯返回a:\< null> c:\< null>< null>
如果Kernel.GetLogicalDriveStrings(lLenOflDrives,lPointerToMemory)那么
Or how to improve the code?

Thanks

PS I added the +1 because as I understand the GetLogicalDriveStrings doc
there will be an uncounted null at the end for Unicode. Agree?

Dim lDrives As String
Dim lLenOflDrives As Integer
Dim lPointerToMemory As IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0, Nothing)
Dim lDrivesSB As New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0, ChrW(33), lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''Get the list of dirves. Returns a:\<null>c:\<null><null>
If Kernel.GetLogicalDriveStrings(lLenOflDrives, lPointerToMemory) Then




如果你改变了你的GetLogicalDriveStrings声明,以便最后的

参数是一个Char(),你可以这样简单地调用它。


Dim buffer(lLenOflDrives - 1)作为Char

如果Kernel.GetLogicalDriveStrings(lLenOflDrives,buffer)> 0然后


Mattias


-

Mattias Sj?gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com

请回复到新闻组。



If you change your GetLogicalDriveStrings declaration so that the last
parameter is a Char(), you can simply call it like this

Dim buffer(lLenOflDrives - 1) As Char
If Kernel.GetLogicalDriveStrings(lLenOflDrives, buffer) > 0 Then

Mattias

--
Mattias Sj?gren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.


只是我,


我不知道你是否对某些托管代码感兴趣逻辑

驱动器。

但是我把它放在这里,当你没有时,也许是其他人在他/她搜索的时候。


设置参考和Imports System.Management

\\\

昏暗的搜索者作为新的ManagementObjectSearcher _

(SELECT * FROM Win32_LogicalDisk)

Dim ManObjOp作为ManagementObject

如果searcher.Get.Count> 1然后

For Each ManObjOp In searcher.Get

Dim win32 As String =" Win32_LogicalDisk =''" &

ManObjOp(" Name")。ToString& "''"

Dim ManObjLogD As New ManagementObject(win32)

For each diskProperty As PropertyData In

ManObjLogD.Properties
如果不是diskProperty.Value则没有那么

Console.WriteLine _

(" {0} = {1}",diskProperty.Name, diskProperty.Value)

结束如果

下一页

下一页

结束如果

///

Cor
Just Me,

I don''t know if you are interested in some managed code to get logical
drives.
However I place it here, when you not, maybe somebody else when he/she is
searching.

set a reference and Imports System.Management
\\\
Dim searcher As New ManagementObjectSearcher _
("SELECT * FROM Win32_LogicalDisk")
Dim ManObjOp As ManagementObject
If searcher.Get.Count > 1 Then
For Each ManObjOp In searcher.Get
Dim win32 As String = "Win32_LogicalDisk=''" &
ManObjOp("Name").ToString & "''"
Dim ManObjLogD As New ManagementObject(win32)
For Each diskProperty As PropertyData In
ManObjLogD.Properties
If Not diskProperty.Value Is Nothing Then
Console.WriteLine _
("{0} = {1}", diskProperty.Name, diskProperty.Value)
End If
Next
Next
End If
///
Cor


只是我,

首先,我会改进它通过使用Environment.GetLogicalDrives代替。


你有没有理由不使用Environment.GetLogicalDrives?

根据Adam的书Marshal.PtrToStringAuto( IntPtr,Integer)

* NOT *终止于第一个空字符,其中

Marshal.PtrToStringAuto(IntPtr)。你确定它会被截断

&不仅仅是调试器在null char之后停止显示?记住

调试器将null char视为字符串终止符!


如果我实际需要调用Kernel32.GetLogicalDriveStrings,我会使用

Marshal.AllocHGlobal而不是Marshal.StringToHGlobalAuto,因为

Marshal.StringToHGlobalAuto更适用于需要将字符串传递给

Win32时,不返回Win32中的字符串...


类似于:

Dim lDrives As String

Dim lLenOflDrives As Integer = Kernel.GetLogicalDriveStrings(0,

IntPtr.Zero)

Dim lPointerToMemory As IntPtr = Marshal.AllocHGlobal(lLenOflDrives

* 2)

Dim rc As Integer = Kernel.GetLogicalDriveStrings(lLenOflDrives,

lPointerToMemory)

如果rc<> 0然后

lDrives = Marshal.PtrToStringAuto(lPointerToMemory,

lLenOflDrives)''文本首先为null,例如a:\

Marshal .FreeHGlobal(lPointerToMemory)

Dim drives()As String = lDrives.Split(ControlChars.NullChar)

结束如果


有关P / Invoke的信息,我通常会参考Adam Nathan的书.NET

和COM - The Complete Interoperability Guide。来自SAMS Press。


希望这有帮助

Jay

"只是我 < GR **** @ a-znet.com>在消息中写道

新闻:eI ************* @ TK2MSFTNGP09.phx.gbl ...
Just Me,
First I would "improve it" via using Environment.GetLogicalDrives instead.

Is there a reason you are not using Environment.GetLogicalDrives?
According to Adam''s book Marshal.PtrToStringAuto(IntPtr, Integer) should
*NOT* terminate at the first null character, where as the
Marshal.PtrToStringAuto(IntPtr) does. Are you certain its getting truncated
& not simply the Debugger stops displaying after the null char? Remember the
Debugger treats the null char as a string terminator!

If I actually needed to call Kernel32.GetLogicalDriveStrings I would use
Marshal.AllocHGlobal instead of Marshal.StringToHGlobalAuto, as
Marshal.StringToHGlobalAuto is more for when you need to pass a string into
Win32, not return a string from Win32...

Something like:
Dim lDrives As String
Dim lLenOflDrives As Integer = Kernel.GetLogicalDriveStrings(0,
IntPtr.Zero)
Dim lPointerToMemory As IntPtr = Marshal.AllocHGlobal(lLenOflDrives
* 2)
Dim rc As Integer = Kernel.GetLogicalDriveStrings(lLenOflDrives,
lPointerToMemory)
If rc <> 0 Then
lDrives = Marshal.PtrToStringAuto(lPointerToMemory,
lLenOflDrives) ''Text to first null, e.g, a:\
Marshal.FreeHGlobal(lPointerToMemory)
Dim drives() As String = lDrives.Split(ControlChars.NullChar)
End If

For information on P/Invoke I normally reference Adam Nathan''s book ".NET
and COM - The Complete Interoperability Guide" from SAMS Press.

Hope this helps
Jay
" Just Me" <gr****@a-znet.com> wrote in message
news:eI*************@TK2MSFTNGP09.phx.gbl...
以下几乎可行。<问题是Marshal.PtrToStringAuto似乎终止于第一个
null所以我没有得到完整的字符串。

有关如何解决此问题的任何建议吗?或者如何改进代码?

谢谢PS我添加了+1,因为据我所知GetLogicalDriveStrings doc
会有一个不计数的null结束Unicode。同意?

Dim lDrives As String
Dim lLenOflDrives as Integer
Dim lPointerToMemory as IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0,Nothing)
Dim lDrivesSB作为New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0,ChrW(33),lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''获取列表迪尔维斯返回a:\< null> c:\< null>< null>
如果Kernel.GetLogicalDriveStrings(lLenOflDrives,lPointerToMemory)那么
''如果声明了GetLogicalDriveStrings则需要使用PtrToStringAnsi
CharSet.Ansi
lDrives = Marshal.PtrToStringAuto(lPointerToMemory,lLenOflDrives + 1)
''文本首先为null,例如a:\
Marshal.FreeHGlobal(lPointerToMemory)
''查看aDrive是否在列表中
DriveExists = InStr(1,lDrives,drive,CompareMethod.Text)
结束如果
The following almost works.
The problem is Marshal.PtrToStringAuto seems to terminate at the first
null so I don''t get the full string.

Any suggestions on how to fix this?
Or how to improve the code?

Thanks

PS I added the +1 because as I understand the GetLogicalDriveStrings doc
there will be an uncounted null at the end for Unicode. Agree?

Dim lDrives As String
Dim lLenOflDrives As Integer
Dim lPointerToMemory As IntPtr
lLenOflDrives = Kernel.GetLogicalDriveStrings(0, Nothing)
Dim lDrivesSB As New StringBuilder(lLenOflDrives + 1)
lDrivesSB.Insert(0, ChrW(33), lLenOflDrives + 1)
lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
''Get the list of dirves. Returns a:\<null>c:\<null><null>
If Kernel.GetLogicalDriveStrings(lLenOflDrives, lPointerToMemory) Then
''Would need to use PtrToStringAnsi if GetLogicalDriveStrings were declared
CharSet.Ansi
lDrives = Marshal.PtrToStringAuto(lPointerToMemory, lLenOflDrives + 1)
''Text to first null, e.g, a:\
Marshal.FreeHGlobal(lPointerToMemory)
''See if aDrive is in the list
DriveExists = InStr(1, lDrives, drive, CompareMethod.Text)
End If



这篇关于以下元帅代码几乎可行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆