在 C# 中编组非托管变量
Marshal unmanaged variables in c#
我正在我的 C# 代码中导入非托管 dll。 .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.
好的,我找到答案了
[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));
不要忘记在不需要变量时释放已分配的 space。
我正在我的 C# 代码中导入非托管 dll。 .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.
好的,我找到答案了
[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));
不要忘记在不需要变量时释放已分配的 space。