【问题标题】:VB.Net why is my marshaled structure updated when passed ByVal but not when passed ByRefVB.Net 为什么我的封送结构在通过 ByVal 时更新但在通过 ByRef 时没有更新
【发布时间】: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


    【解决方案1】:

    midiOutPrepareHeader 方法的第二个参数是“指向标识要准备的缓冲区的 MIDIHDR 结构的指针”。你的IntPtr 就是那个指针。通过声明参数ByRef,您传递的是指向指针的指针,而不是传递指针本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      相关资源
      最近更新 更多