我尝试将这些VB6类型转换为VB.NET世界。
Type TRACK_DATA
Dim reserved As Byte
Dim Control As Byte
Dim Tracknumber As Byte
Dim reserved1 As Byte
Dim address As Long
End Type
Type CDTOC
Dim Length As Long
Dim FirstTrack As Byte
Dim LastTrack As Byte
Dim Tracks(100) As TRACK_DATA
End Type
目前的尝试失败了
<System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Size:=8)>
Structure TRACK_DATA
Public reserved As Byte
Public Control As Byte
Public Tracknumber As Byte
Public reserved1 As Byte
Public address As UInteger
End Structure
<System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Size:=806)>
Structure CDROM_TOC '4 + 1 + 1 + 800 = 806
Public Length As UInteger
Public FirstTrack As Byte
Public LastTrack As Byte
Public Tracks() As TRACK_DATA
End Structure
...
Dim MyCD As CDTOC
ReDim MyCD.Tracks(100)
任何提示如何做到这一点?
传递参数并将它们返回到外部dll,所以我使用编组,但Marshal.SizeOf(MyCD)
返回错误的值(12)如果我不使用InterOp Size,并且,请注意所有的尝试与StructureToPtr结束错误。
以下代码,如果有任何用途可以理解:
Toc_len = Marshal.SizeOf(MyCD)
Dim Toc_ptr As IntPtr = Marshal.AllocHGlobal(CInt(Toc_len))
'open the drive
...
'access to the TOC
DeviceIoControl(hFile, IOCTL_CDROM_READ_TOC, IntPtr.Zero, 0, Toc_ptr, Toc_len, BytesRead, IntPtr.Zero)
'copy back the datas from unmanaged memory
'fails here !
MyCD = Marshal.PtrToStructure(Toc_ptr, CDTOC.GetType())
答案 0 :(得分:9)
这里的链接看起来有一些相当广泛的讨论(包括示例代码): https://social.msdn.microsoft.com/Forums/en-US/3df9e61d-440f-4bea-9556-b2531b30e5e6/problem-with-deviceiocontrol-function?forum=vblanguage
您的结构只是缺少Tracks
成员上的属性,告诉编译器它是一个内联的100个成员数组。
从链接:
<StructLayout(LayoutKind.Sequential)> _
Structure CDROM_TOC
Public Length As UShort
Public FirstTrack As Byte
Public LastTrack As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=100)> _
Public TrackData() As TRACK_DATA
End Structure
(该链接还包括我在此处省略的结构中的一些便利功能。)