この関数を使用して、低レベルのキーボード フックからキーストロークを検索しています...
Const UnicodeBufferExSize As Integer = 64
Public Declare Function ToUnicodeEx Lib "user32" (wVirtKey As UInteger,
wScanCode As UInteger,
lpKeyState As Byte(),
<Out()>
<MarshalAs(UnmanagedType.LPWStr, SizeConst:=UnicodeBufferExSize)> '<-- Note this line (#A)
ByVal lpChar As System.Text.StringBuilder,
cchBuff As Integer,
wFlags As UInteger,
dwhkl As IntPtr) As Integer
...
Dim SB As New System.Text.StringBuilder(UnicodeBufferExSize) '<-- And this one (#B)
ToUnicodeEx(CUInt(lParam.vkCode),
CUInt(lParam.scanCode),
KeyState,
SB,
SB.Capacity, '<-- And this (#C)
0,
InputLanguage.CurrentInputLanguage.Handle)
GC.Collect()
Return SB.ToString()
ToUnicodeExへの呼び出しは、入力されるバッファーのサイズを示すパラメーターを取りますStringBuilder
(行 #C)。
容量の引数を指定せずに を作成しStringBuilder
(行 #B、現在の実装ではリフレクションからデフォルトで 16 の容量になっているようです)、SizeConst
(行 #A) を省略した場合、呼び出しは通常成功しますが、マネージド ヒープ破損例外が発生することがあります。
今、私はUnicodeBufferExSize
問題を解決することを期待して定数を追加しましたが、そうしているようです-しかし、それが本当に修正されたのか、それとも単にまれになったのかはわかりません.
単にバッファサイズを渡すだけでは不十分な理由を誰かが説明できますか? また、私の解決策が正しいかどうか、または微妙なバグがあるかどうかも確認してください。
(への呼び出しGC.Collect()
は問題をより迅速にトリガーし、デバッグを支援するためにのみ使用されていることに注意してください。)
ハンスによる(最初の)コメントに加えて...
Problem signature:
Problem Event Name: APPCRASH
Application Name: Glue.exe
Application Version: 3.1.3.0
Application Timestamp: 52001dc3
Fault Module Name: ntdll.dll
Fault Module Version: 6.1.7601.17725
Fault Module Timestamp: 4ec4aa8e
Exception Code: c0000005
Exception Offset: 00000000000532d0
OS Version: 6.1.7601.2.1.0.256.1
Locale ID: 2057
Additional Information 1: 355b
Additional Information 2: 355bc389704a5d6b4e279d0f0bd3355a
Additional Information 3: 02ad
Additional Information 4: 02ad05628a0a65c888b4805dfd9c6b58