Я пытаюсь вызвать Windows Multimedia API (winmm.dll) из C #, используя P / Invoke.
Причина в том, что я пытаюсь портировать некоторый неуправляемый код C ++, который генерирует тоны с различной частотой и не имеет успеха с управляемыми библиотеками, и поэтому пытаюсь напрямую повторно использовать код C ++, который уже работает очень хорошо.
Я начал с того, что пошел на pinvoke.net и посмотрел оттуда подписи различных функций и вставил в предоставленные строки DllImport.
Однако меня смутило очевидное несоответствие того, каквещи отображаются.
Например, функция waveOutPrepareHeader ( MS Docs , pinvoke.net ).Второй аргумент - это указатель на структуру WAVEHDR.Страница pinvoke.net имеет смысл для меня в том смысле, что это должен быть IntPtr, который указывает на блок памяти, содержащий структуру.Я подготовил это, используя GlobalAlloc с GMEM_FIXED, а затем Marshal.StructureToPtr, чтобы заполнить данные.Затем я передаю указатель, возвращенный из GlobalAlloc как IntPtr, в функцию.
Однако для других функций, таких как waveOutOpen ( MS Docs , pinvoke.net ) и waveOutWrite( MS Docs , pinvoke.net ), указатели на структуры передаются как ссылка на управляемую структуру, соответствующую неуправляемой структуре.
Почему разница?Как это работает при передаче ссылки на управляемую структуру?Слой P / Invoke просто обнаруживает это и выполняет внутреннее сопоставление?
Мне интересно, потому что в некоторых случаях я получаю нарушения доступа во время выполнения кода и поэтому пытаюсь пройти через вызовы функцийс тонкой зубной расческой, и это просто не имеет смысла для меня.