2009-06-29 32 views
0

最後の行にスローされた例外、保護されたメモリの読み書きを試みているという例外が表示されています。私はここで間違って何をしていますか?おかげで、MSDNからプロテクトされたメモリ例外の読み込み/書き込み

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 

答えて

1

LB_GETTEXTLEN

は、戻り値はヌル文字を除く、TCHAR単位で、文字列の長さです。特定の条件下では、この値は実際にテキストの長さよりも長くなることがあります。詳細については、次の「備考」セクションを参照してください。

LB_GETTEXT

文字列を受け取るバッファへのポインタ。その後LPARAMにキャストされるタイプのLPTSTRです。バッファーには、ストリングと終了ヌル文字のための十分なスペースが必要です。 LB_GETTEXTメッセージの前にLB_GETTEXTLENメッセージを送信して、文字列のTCHARの長さを取得することができます。

ヌルTCHARを1つ追加するスペースが必要です。しかし、私はあなたのコードのいくつかの他の問題を参照してください:

  • あなたのシステムはWinNTですか?それでlb_gettextlenはTCHARの長さを返し、NTシステムでは1つのTCHARは2バイト長です
  • 私はAllocHGlobalを参照していますが、FreeHGlobalは表示されません。メモリーリーク?
  • UTF8エンコーディングを使用してバイト配列を文字列に変換するのはなぜですか? Unicodeを使用する必要があります。
  • SendMessageインターフェイスは、x64ポインタを想定していないため、潜在的に危険です。

更新:一般的には、あなたのコードは次のようになります。

[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()); 
    } 
} 
関連する問題