1

MSVC 64 ビット コンパイラを使用して、以下のコードの論理エラーを解決しようとしています。

このコードは、以前は 32 台のマシンで問題なく動作していました。

return ((ULONG) DupThreadHandle);

64 ビットの世界では、すべてのスレッド ハンドルが 64 ビット (実際には 6 バイト) であることを知りました。したがって、宛先の型が 32 ビットの ULONG であるため、このコードは明らかに間違っています。

しかし、msdn は basetsd.h をインクルードして C コードの 64 ビット移植のためにタイトルで述べたヘルパー関数を使用することを推奨しています。

しかし、私の質問は、そのようなヘルパー関数がどのように概念的に 6 バイト アドレスを 4 バイト アドレスに変更するのかということです。すでにスレッドが6バイトアドレスに配置されているためです。この 4 バイトのアドレスはどの程度意味がありますか? 宛先タイプを変更したくありません。問題は再帰的な警告になるためです。

4

1 に答える 1

2

Microsoft hereによると、...

移植を容易にするために、これらのシステム ハンドルは、64b プラットフォームで 64b に拡張された 32b 値のままにする必要があるという決定が下されました。つまり、個々のハンドル型は引き続き HANDLE 型に基づいており、void * にマップされるため、ハンドルのサイズはポインターのサイズになります。つまり、32b では 4 バイト、64b では 8 バイトです。ただし、64b プラットフォームのハンドルの実際の値 (つまり、意味のあるビット) は下位 32b に収まり、上位ビットは符号を運ぶだけです。

こちらもご覧ください。

Handle64toHandle() 関数の効果は、64 ビット型と 32 ビット型の間でキャストするだけで自分で複製できますが、これは大きな問題ですが、signed型を使用してキャストする必要があります。上記で説明したように、タイプを使用したキャストは、unsignedMicrosoft のアドレスの扱いを符号付き数量として扱います。タイプを使用するようにキャスティングを変更signedすれば、問題ないはずです。ただし、そのようなアドレスを確実に保存する必要がありますsigned32 ビット型。上位ビットのすべて 1 の状態を失うことなく、後で適切な 64 ビット型に適切に変換されます。従来の理由でそれができない場合 (つまり、変更できない従来のコードの一部である 32 ビットの符号なし整数に格納するなど)、変換を行うときに、これらの符号なしの値を符号付きの値にキャストしてください。 64 ビットに戻ります。

于 2013-01-30T17:06:13.967 に答える