我被一个异常告知,在最后一行被抛出,我正在尝试读取/写入受保护的内存。我在这做错了什么?感谢
int count = (int)WinApi.SendMessage(_chatHwnd, WinApi.LB_GETCOUNT, 0, 0);
Debug.WriteLine("count=" + count);
StringBuilder sb = new StringBuilder(count * 20);
for (int i = _lastReadPosition; i < count; i++) {
int len = (int)WinApi.SendMessage(_chatHwnd, WinApi.LB_GETTEXTLEN, i, 0);
IntPtr text = Marshal.AllocHGlobal(len);
byte[] itemText = new byte[len];
WinApi.SendMessage(_chatHwnd, WinApi.LB_GETTEXT, i, text.ToInt32());
Marshal.Copy(text, itemText, 0, len);
string s = System.Text.Encoding.UTF8.GetString(itemText);
sb.Append(s);
}
Debug.WriteLine("analise"); <- EXCEPTION THROWN HERE
答案 0 :(得分:1)
来自msdn:
<强> LB_GETTEXTLEN 强>
返回值是字符串的长度,在TCHAR中,不包括终止空字符。在某些条件下,此值实际上可能大于文本的长度。有关更多信息,请参阅以下备注部分。
<强> LB_GETTEXT 强>
指向将接收字符串的缓冲区的指针;它是LPTSTR类型,随后被转换为LPARAM。缓冲区必须有足够的空间用于字符串和终止空字符。可以在LB_GETTEXT消息之前发送LB_GETTEXTLEN消息,以检索字符串的长度(在TCHAR中)。
您需要为一个额外的空TCHAR提供空间。但是,我在您的代码中看到了其他几个问题:
更新:通常,您的代码必须如下所示:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder lParam);
private void Form1_Shown(object sender, EventArgs e)
{
int count = (int)SendMessage(_chatHwnd, WinApi.LB_GETCOUNT, IntPtr.Zero, IntPtr.Zero);
StringBuilder sb = new StringBuilder(count * 20);
for (int i = _lastReadPosition; i < count; i++)
{
int len = (int)SendMessage(_chatHwnd, WinApi.LB_GETTEXTLEN, (IntPtr)i, IntPtr.Zero);
StringBuilder LineBuilder = new StringBuilder(len + 1);
SendMessage(_chatHwnd, WinApi.LB_GETTEXT, (IntPtr)i, LineBuilder);
sb.Append(LineBuilder.ToString());
}
}