Маршал неуправляемых переменных в C#
Я импортирую неуправляемую DLL на мой код C#. Файл.h описывает методы, как показано ниже
DLL_API int __stdcall SetConfiguration(IN char* configuration);
DLL_API int __stdcall GetErrorMessage_UTF16(
INOUT int* errorGroup,
INOUT char* errorCode, /*It must be allocated by the caller and its length must be at least 10 bytes, otherwise the function will crash*/
INOUT wchar_t *messageText,
IN int bufferLength);
Мне удалось вызвать метод SetConfiguration
[DllImport(DllPath, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
private static extern int SetConfiguration([In] MarshalAs(UnmanagedType.LPStr)] string configuration);
Предоставление простой строки C# сделало свою работу.
Теперь я пытаюсь метод GetErrorMessage_UTF16 без успеха. Итак, как мне определить длину errorCode и как объявить переменную wchar_t *messageText?
Я пробовал что-то вроде этого, но это не похоже на работу
[DllImport(DllPath, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
private static extern int GetErrorMessage_UTF16(
[In, Out] int errorGroup,
[In, Out] [MarshalAs(UnmanagedType.LPStr)] string errorCode,
[In, Out] [MarshalAs(UnmanagedType.LPStr)] StringBuilder messageText,
[In] int bufferLength);
Что бы я ни пытался, я получаю
Exception thrown at 0x0f5d1235 (Mydll.dll) in Mydll.exe: 0xc0000005: Access violation writing location 0x067d1000
If there is a handler for this exception, the program may be safely continued.
1 ответ
Решение
Хорошо, я нашел ответ
[DllImport(DllName, EntryPoint = "GetErrorMessage_UTF16", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int GetErrorMessage_UTF16(out int errorGroup, IntPtr errorCode, IntPtr messageText, int bufferLength);
Для errorCode и messageText создайте указатель, а затем выделите размер.
IntPtr errorCode = Marshal.AllocHGlobal(10);
IntPtr messageText = Marshal.AllocHGlobal(someBufferLength * sizeof(char));
Не забудьте освободить выделенное пространство, когда переменные не нужны.