0

我正在尝试使用 P/Invoke 从 C# 调用 Windows 多媒体 API (winmm.dll)。

原因是我正在尝试移植一些非托管 C++ 代码,这些代码以不同的频率生成音调,并且对托管库没有运气,因此我试图直接重用已经运行良好的 C++ 代码。

我首先访问 pinvoke.net 并查找各种函数签名并从那里粘贴到提供的 DllImport 行中。

然而,让我感到困惑的是,事物的映射方式明显不一致。

例如,waveOutPrepareHeader 函数(MS Docspinvoke.net)。第二个参数是指向 WAVEHDR 结构的指针。pinvoke.net 页面对我来说很有意义,因为它应该是一个 IntPtr,它指向包含该结构的内存块。我使用 GlobalAlloc 和 GMEM_FIXED 准备了这个,然后 Marshal.StructureToPtr 来填充数据。然后,我将从 GlobalAlloc 返回的指针作为 IntPtr 传递给函数。

但是,对于 waveOutOpen ( MS Docs , pinvoke.net ) 和 waveOutWrite ( MS Docs , pinvoke.net ) 等其他函数,指向结构的指针作为 ref 传递给与非托管结构匹配的托管结构。

为什么有区别?将 ref 传递给托管结构时它是如何工作的?P/Invoke 层是否只是检测到这一点并在内部进行映射?

我想知道,因为在某些情况下,我在代码运行时遇到了访问冲突,所以我试图用细齿梳来完成函数调用,这对我来说没有意义。

4

0 回答 0