Объявление Win32 API waveInGetErrorText в C # - PullRequest
1 голос
/ 14 марта 2019

нужно позвонить

MMRESULT waveInGetErrorText(
   MMRESULT mmrError,
   LPTSTR   pszText,
   UINT     cchText
);

Из кода C #. Не нашел декларацию на PINVOKE.net. Описание функции здесь

MMRESULT - это просто значение uint. 0 - без ошибок .. любое другое значение до 20 - ошибки.

Пробовал много шаблонов. Всегда возвращайте пустую строку.

[DllImport("Winmm", EntryPoint = "waveInGetErrorText")]
public static extern uint waveInGetErrorText(uint mmrError, IntPtr pszText, uint cchText);

При звонке.

uint r = 12 // for example return value is 12
uint szErrorMessage = 128;
string errorMessage = new string(' ', (int) szErrorMessage);
IntPtr strPtr = Marshal.StringToBSTR(errorMessage);

r = waveInGetErrorText(r, strPtr, szErrorMessage);

Возвращаемая строка всегда пуста зарезервировано 128 байтов пробелов. Пробовал ref и out безуспешно ..

Просьба, есть идеи почему?

1 Ответ

2 голосов
/ 14 марта 2019

Ваше определение:

public static extern uint waveInGetErrorText(uint mmrError, 
                                             IntPtr pszText, 
                                             uint cchText);

... недостаточно, чтобы сообщить .NET, что IntPtr pszText выводит что-либо. По умолчанию все параметры имеют компилятор с [in] маршальными атрибутами. Таким образом, ваше вышеупомянутое определение эквивалентно:

public static extern uint waveInGetErrorText([in] uint mmrError, 
                                             [in] IntPtr pszText, 
                                             [in] uint cchText);

Теперь, если у вас было такое определение:

int CountRecords (out int numErrors)

... компилятор превращает это в:

int CountRecords ([out] out int numErrors)

... Я верю. В любом случае, out (любая форма) говорит компилятору ожидать чего-то от p-invoke. Поскольку вы не указали out или [out], после завершения вызова ничего не передается обратно в параметр.

Теперь вы можете использовать out string, но StringBuilder проще. Некоторые типы, такие как StringBuilder, распознаются .NET как "эй, для этого параметра я ожидаю что-то взамен" . out является необязательным.

Измените ваше определение на:

[DllImport("Winmm", EntryPoint = "waveInGetErrorText")]
public static extern uint waveInGetErrorText(uint mmrError, StringBuilder text, uint cchText);

Я полагаю, вы должны называть это так:

uint r = 12 // for example return value is 12
StringBuilder data = new StringBuilder(255);
r = waveInGetErrorText(r, data, data.Capacity);

Скажите мне больше

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...