2016-11-18 23 views
0

Я импортирую неуправляемую dll на свой код C#. .h файл описывает методы, как показано нижеНеуправляемые переменные маршала в C#

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. 
+0

Первый arg должен быть 'out int', второй arg выглядит как StringBuilder, третий arg - LPWStr –

ответ

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)); 

Не забудьте освободить выделенное пространство, когда переменные не нужны.