现在有一个C++写的DLL,有一个struct:
typedef struct USER_INFO { char* user_id; char* user_name; char* user_icon; unsigned int user_icon_len; }
一个函数:
int __stdcall get_user_info(void* user_info);
要在C#里调用这个函数,传入USER_INFO结构,来获取用户信息。
C#里我这么写:
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct UserInfo { public IntPtr user_id; public IntPtr user_name; public IntPtr user_icon; public IntPtr user_icon_len; } IntPtr infosIntptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UserInfo))); i = get_user_info(infosIntptr);
UserInfo info = (UserInfo)Marshal.PtrToStructure(infosIntptr, typeof(UserInfo));
可以调用成功,但是用Marshal.PtrToStringAuto(info.user_name)来获取struct的属性,总是不正确,全是乱码,user_icon也不对。
后来把struct改成这样:
[StructLayoutAttribute(LayoutKind.Sequential)] public struct UserInfo { [MarshalAs(UnmanagedType.ByValTStr)] public string user_id; [MarshalAs(UnmanagedType.ByValTStr)] public string user_name; [MarshalAs(UnmanagedType.ByValArray)] public byte[] user_icon; public int user_icon_len; }
也是无法正确取到UserInfo的字段属性,请问高手这个struct要怎么声明,怎么传参?
public struct UserInfo { public string user_id; public string user_name; public string user_icon; public uint user_icon_len; }
结构体这样封应该没什么问题
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct USER_INFO { /// char* [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] public string user_id; /// char* [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] public string user_name; /// char* [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] public string user_icon; /// unsigned int public uint user_icon_len; }
那个函数的话参数改成Inptr类型就行