私はCreateFileによって返される無効な値がINVALID_HANDLE_VALUEであることを知っています。しかし、私もRAIIを使うことが好きなので、shared_ptr(このように: shared_ptr<void> handle (CreateFile(args),&CloseHandle)
) にハンドルを貼り付けて、ハンドルが閉じていることを確認するのは非常に魅力的です。 RAIIを行うこの簡単で簡単な方法で私の懸念は、CreateFileがHANDLE値としてNULLを返すことができる場合です。CreateFileはNULLを返しますか?
答えて
NULL
は有効なハンドル値ではありません。いくつかのWindows API関数がエラーを示すためにNULL
を返すという事実から、これを識別することができます。ハンドルを処分する機能は1つで、CloseHandle
なので、NULL
は有効なHANDLE
の値ではありません。したがってCreateFile
はNULL
を返すことはできません。
レイモンド・チェンは、このトピックに触れるブログ記事を書きました:Why are HANDLE return values so inconsistent?。
今、私はshared_ptr<>
について何も知らないので、あなたのアイデアが適切かどうかについてコメントをしたくありません。あなたが尋ねた直接の質問に答えるだけです。
"無効な"戻り値がINVALID_HANDLE_VALUEである関数からもNULLが返されないことを知りませんでした。これは本当ですか?あなたの議論では、そのような 'CloseHandle'は、無効なハンドルが渡されたときに、(カーネルハンドルである限り)どの関数がそれを返しても検出することができます。しかし、OTOHのCloseHandleは、**無効な値を渡す**を持っていません。 – valdo
@valdo私の議論は、 'CloseHandle'は、無効なハンドルがCreateFileか、戻り値として' NULL'を使う別のAPIかどうかを知らないということです。もう一つの簡単な議論は、 'CreateFile'が' NULL'を返すと、別の関数がどのようにシグナルに失敗するのか? –
申し訳ありませんが、私はあなたの議論を理解しました。それはおそらく正しいでしょう。しかし、*理論的には*これは何も証明していません。標準の 'CloseHandle'によれば、無効なハンドルを渡しただけで、別の(無関係な)リソースを閉じるなど、何の害もなく黙って失敗することを認識する必要はありません。それはあなたの問題です。 'CreateXXXX'の戻り値をチェックし、ハンドルが無効な場合は' CloseHandle'を呼び出さないようにするのはあなたの責任です。しかし、実際に言えば、私は 'NULL'と' INVALID_HANDLE_VALUE'の両方が非ハンドル値として予約されていると思います。 – valdo
一般的な方法でHANDLEの妥当性をテストする場合は、NULL
とINVALID_HANDLE_VALUE
の両方を確認してください。
しかし、がNULL
を返すことができるかどうかは、RAIIと関係がありません。 HANDLE
を共有ポインタで動作させるためには、有効性のテストと割り当て解除のカスタムコードを提供する必要があります。共有ポインタクラスではなく、これらのチェックを制御します。
言い換えれば、共有ポインタにあるかどうかに違いはありません。通常はHANDLE
です。チェックはまったく同じで、いずれかの方法で指定する必要があります。
実際には 'NULL'か' INVALID_HANDLE_VALUE'を渡して 'CloseHandle'を呼び出すのはかなり害です。それは間違いですが、これには害はありません。私はこのように「ハンドル」を包んでいないと認めます。別注のRAIIクラスは仕事をうまくやってくれるでしょう。私はそれが何十倍もの出来事が終わったと確信しています。 +1 –
@David Heffernan私は、より完全な解決策があなた自身のハンドル管理クラスを書くことであることをよく知っています。これをその方向の一歩と考えてみましょう。 – Dan
なぜ私は、CreateFileがNULLを返すことができ、RAIIと何が関係があるかを気にします。値がnullの場合、shared_ptrがカスタムデストラクタを呼び出さない可能性があります。(少なくともブーストのために)コードを深く見れば、それはとにかくやっているように見えます。また、shared_ptrを返すカスタム作成関数を使用する場合、nullハンドルを含むものと何も含まないshared_ptrを区別するのは面倒です – Dan
- 1. CreateFile()はINVALID_HANDLE_VALUEを返しますが、GetLastError()はERROR_SUCCESSです
- 2. EditText.getText()はnullを返しますか?
- 3. java.io.ByteArrayOutputStream.toByteArray()はnullを返しますか?
- 4. Reallocはnullを返しますか?
- 5. RadioInfo.getCurrentNetworkName()はnull値を返しますか?
- 6. Android:getSearchableInfo(getComponentName())はnullを返しますか?
- 7. Android bitmap.getwidthはnullを返しますか?
- 8. QGLBuffer :: mapはNULLを返しますか?
- 9. WindowsIdentity.GetCurrent()はnullを返しますか?
- 10. Java Singleton.getInstance()はnullを返しますか?
- 11. javax.persistence.Query.getResultList()はnullを返しますか?
- 12. Type.GetType()nullを返します
- 13. ConfigurationManager.AppSettings - Nullを返します
- 14. NSURLRequest nullを返します
- 15. SurfaceHolder.lockCanvas()nullを返します
- 16. MYSQL COUNTがNULLを返しますか?
- 17. SharedObject.getLocal()はnullを返します
- 18. geocoder.getFromLocationNameはnullのみを返します
- 19. getSupportActionBar()はRobolectricでnullを返します
- 20. android-sharedpreferencesはnull値を返します
- 21. cvCapturefromCAM()はNULLを返します。
- 22. mclapplyはランダムにNULLを返します
- 23. NSData to NSStringはnullを返します
- 24. Intent.getExtras()は常にnullを返します
- 25. Android ArrayList iteratorはnullを返します
- 26. Context.CurrentMiningModelはUDFでnullを返します
- 27. ExtractAssociatedIconはnullを返します
- 28. mysqlはNULLを返します。
- 29. GetTemplateChildは常にnullを返します
- 30. event.source()はアンドロイドでnullを返します
このようなことをするときは注意が必要です。参照してください:http://stackoverflow.com/questions/1562421/making-a-handle-raii-compliant-using-shared-ptr-with-a-custom-deleter – tenfour
この種のリソース用のRAIIラッパーを作成しても問題ありません。しかし、あなたが本当に**共有する必要がない限り、 'shared_ptr'を使わないでください。 'shared_ptr'が故意にこれを防ぐので、' HANDLE'への直接的なキャストのような便利なアクセスはありません。 – valdo
優れたポイント。 unique_ptrはおそらくこの努力のレベルで行くより良い方法でしょう。 – Dan