1

私自身のプログラムでは、このコードを使用してツールチップ バルーン ウィンドウをアプリケーションに追加しようとしています: http://www.codeproject.com/Articles/4991/Balloon-Tips-Galore (ソース コードはこちらから入手できます)

デモ プログラムをコンパイルしてみましたが、32 ビットの Windows 7 では正常に動作しますが、64 ビットの Windows 7 で使用しようとすると、プログラムがクラッシュします。VS2010 でクラッシュをデバッグしようとすると、次のメッセージが表示されます。

ここに画像の説明を入力

デバッガーは、ソースコードが利用できない領域にあり、次のように表示されますCall stack location: ntdll.dll!0000000076fe40f2()

64ビットでクラッシュしないようにするにはどうすればよいですか?

4

1 に答える 1

4

Windows Server 2003 x64 (現時点で手元にある唯一の 64 ビット環境) で C# のデモをクラッシュさせることはできませんが、コードに欠陥があるため、予期しない動作が見られるのは理にかなっています。

編集:元のコードを使用して Windows Server 2008 R2 x64 でのクラッシュを再現し、修正の有効性を検証しました。

Christian.K が指摘するように、この問題は以前にも指摘されていました。メソッドを呼び出すときは、指定したメモリ ブロックに有効なデータが含まれていない場合にのみ、3 番目のパラメーターMarshal.StructureToPtrを渡す必要があります。これはドキュメンテーションでかなり明示的に呼び出されているため、元の作成者がどのように間違えたのかはわかりません。truefDeleteOld

この場合、データは を呼び出して前の行に割り当てられたばかりMarshal.AllocHGlobalなので、有効なデータが含まれていないため、削除/解放しないでください。変更は簡単です。3 番目のパラメーターtrueを に変更しますfalse。残念ながら、サンプル プロジェクトでは相互運用コードが 3 つの異なるクラスに分散しているため、複数の場所を変更する必要があります。あなたが探しているパターンはこれです:

IntPtr ptrStruct = Marshal.AllocHGlobal(Marshal.SizeOf(ti));
Marshal.StructureToPtr(ti, ptrStruct, false /* <-- change this from true to false */);

一般的な観察として、コードはMarshal、CLR に自動的に処理させるのではなく、多くの相互運用機能を (クラスのメソッドを使用して) 手動で処理しようとします。私は後者の方法を好みますすべての相互運用を手動で行う方法を完全に理解していますが、システムに管理を任せて、私が犯すミスの数と結果としてのヒープの破損を抑えています。

RhysW氏によると、これまでヒープの破損に遭遇したことはありませんが、.NET コードと Win32 API の間の相互運用を開始すると、非常に一般的になります。.NET Framework はもはやあなたを保護していません。

言いたいことの例として、FMSBalloonTip.SetToolTipメソッドがメソッドを使用してMarshal.StringToHGlobalAuto、ツールチップのタイトルを含む文字列をポインターとしてマーシャリングしていることに注意してください。それは確かに機能しますが (作成者は、終了後にポインターを解放するように注意してくれました)、 4 番目のパラメーターとしてオブジェクトSendMessageを受け入れる関数のオーバーロードを宣言する方がはるかに簡単で、エラーが発生しにくくなります。stringそうすれば、フレームワークは必要なすべての相互運用機能を透過的に処理します。

もちろん、本当の問題は、なぜこのコードが必要なのかということです。最初から利用可能だった組み込みのclassを使用する方がずっとToolTip簡単です。提供されていない必要な機能について言及しなかったのかToolTip、単にそれについて知らないだけなのかはわかりませんが、組み込みクラスを利用できるように設計を再検討することを強くお勧めしますMicrosoft のプログラマーにすべての相互運用機能を処理してもらいます。

探しているバルーンパーツの場合は、必ずクラスのIsBalloonプロパティを設定してください。ToolTipこれは .NET 2.0 まで導入されませんでしたが、サンプル プロジェクトが対象としているのと同じバージョンです。

于 2013-02-14T19:11:16.983 に答える