我一直在努力争取一些系统dll才能工作。我终于想出了如何让它发挥作用,但我不明白为什么。
我需要将结构传递给库函数midiOutPrepareHeader
,并且该结构包含指向我分配的缓冲区的指针以及库设置的一些标志。在声明中我最初有 ByRef
lpMidiOutHdr As IntPtr
。没有明显的错误,但是下面的函数调用总是报告缓冲区还没有准备好" (准备好的旗帜没有设定)。当我最终将其更改为 ByVal
lpMidiOutHdr As IntPtr
时,调用后的结构副本设置了标志并且后续功能正常工作。
(我已经删除了用于检查结构的代码并找出发生了什么,但基本上这使用了PtrToStructure
来解释数据,因此我可以检查它。< / p>
Private Declare Function fmidiOutPrepareHeader Lib "winmm.dll" Alias "midiOutPrepareHeader" (ByVal hMidiOut As Integer, ByVal lpMidiOutHdr As IntPtr, ByVal uSize As Integer) As Integer
Private Declare Function fmidiOutUnprepareHeader Lib "winmm.dll" Alias "midiOutUnprepareHeader" (ByVal hMidiOut As Integer, ByVal lpMidiOutHdr As IntPtr, ByVal uSize As Integer) As Integer
Private Declare Function fmidiOutLongMsg Lib "winmm.dll" Alias "midiOutLongMsg" (ByVal hMidiOut As Integer, ByVal lpMidiOutHdr As IntPtr, ByVal uSize As Integer) As Integer
Public Function midiOutGetDevCaps(ByVal uDeviceID As Integer, ByRef lpCaps As MIDIOUTCAPS) As Integer
Return fmidiOutGetDevCaps(uDeviceID, lpCaps, Marshal.SizeOf(lpCaps))
End Function
Public Function midiOutLongMsg(ByVal hMidiOut As Integer, ByRef MidiOutHdr As MIDIHDR, ByRef MidiOutData As Byte()) As Integer
Dim result As Integer
MidiOutHdr.lpData = Marshal.AllocHGlobal(MidiOutHdr.dwBufferLength) 'allocate unmanaged memory for the data to be copied into. Set the header to point to it
Marshal.Copy(MidiOutData, 0, MidiOutHdr.lpData, MidiOutHdr.dwBytesRecorded)
Dim unmanagedHeader As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(MidiOutHdr))
Marshal.StructureToPtr(MidiOutHdr, unmanagedHeader, True)
result = fmidiOutPrepareHeader(hMidiOut, unmanagedHeader, Marshal.SizeOf(MidiOutHdr))
result = fmidiOutLongMsg(hMidiOut, unmanagedHeader, Marshal.SizeOf(MidiOutHdr))
result = fmidiOutUnprepareHeader(hMidiOut, unmanagedHeader, Marshal.SizeOf(MidiOutHdr))
Marshal.FreeHGlobal(unmanagedHeader)
Marshal.FreeHGlobal(MidiOutHdr.lpData)
MidiOutHdr.lpData = 0
Return result
End Function
任何人都可以解释为什么我在传递值时从数据库中获取数据,但是在通过引用传递时却没有?
非常感谢。 阿德里安
答案 0 :(得分:0)
midiOutPrepareHeader
方法的第二个参数是&#34;指向MIDIHDR结构的指针,用于标识要准备的缓冲区&#34;。你的IntPtr
就是那个指针。通过声明参数ByRef
,您传递的指针指向指针,而不是传递指针本身。