【发布时间】:2014-05-28 02:54:18
【问题描述】:
为了让系统 dll 中的一些调用正常工作,我已经苦苦挣扎了好几个小时。我终于想出了如何让它工作,但我不明白为什么。
我需要将一个结构传递给库函数midiOutPrepareHeader,该结构包含一个指向我分配的缓冲区的指针和库设置的一些标志。在声明中,我最初有 ByReflpMidiOutHdr As IntPtr。没有明显的错误,但是下面的函数调用总是报告缓冲区没有“准备好”(准备好的标志没有设置)。当我最终将其更改为 ByVallpMidiOutHdr As IntPtr 时,调用后的结构副本设置了标志并且后续函数起作用。
(我删除了用于检查结构并找出发生了什么的代码,但基本上这使用PtrToStructure 来“解组”数据,以便我可以检查它)。
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
谁能解释为什么我在按值传递时从 dll 中取回数据,而在按引用传递时却没有?
非常感谢。 阿德里安
【问题讨论】:
标签: .net structure marshalling pass-by-reference pass-by-value