1

Windows HANDLE をシリアル化できるようにしたい:

typedef void *HANDLE

以下を使用してコンパイルしようとすると:

struct Foo
{
    HANDLE file;

protected:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /*version*/)
    {
        ar & file;
    }
};

コンパイル エラーが発生します。

c:\projects\3rdparty\src\boost\include\boost/mpl/print.hpp(51) : warning C4308: negative integral constant converted to unsigned type
        c:\projects\3rdparty\src\boost\include\boost/serialization/static_warning.hpp(92) : see reference to class template instantiation 'boost::mpl::print<T>' being compiled
        with
        [
            T=boost::serialization::BOOST_SERIALIZATION_STATIC_WARNING_LINE<98>
        ]
        c:\projects\3rdparty\src\boost\include\boost/archive/detail/check.hpp(98) : see reference to class template instantiation 'boost::serialization::static_warning_test<B,L>' being compiled
        with
        [
            B=false,
            L=98
        ]
        c:\projects\3rdparty\src\boost\include\boost/archive/detail/oserializer.hpp(313) : see reference to
function template instantiation 'void boost::archive::detail::check_object_tracking<T>(void)' being compiled
        with
        [
            T=Foo
        ]
        c:\projects\3rdparty\src\boost\include\boost/archive/detail/oserializer.hpp(525) : see reference to
function template instantiation 'void boost::archive::detail::save_non_pointer_type<Archive>::invoke<T>(Archive &,T &)' being compiled
        with
        [
            Archive=boost::archive::text_oarchive,
            T=Foo
        ]

しかし、に変更すればfileintすべて問題ありません。HANDLE を int としてシリアル化するように boost に指示するにはどうすればよいですか?

ありがとう

4

2 に答える 2

4

HANDLEで定義されている Windows API 固有のデータ型winnt.hです。MSDNによると、

オブジェクトへのハンドル。この型は次のように宣言されWinNT.hています。

typedef PVOID HANDLE;

これで、オブジェクトのハンドルを表すHANDLEだけであることがわかりました。void *自分がやろうとしていることは何なのかを考えてください。Windows API でオブジェクトへのポインターをシリアル化するのは理にかなっていますか?

代わりに、同等のものを取得するために必要なものをシリアル化してみてくださいHANDLE。メンバーの名前から判断すると、あなたが使っていたと思いますCreateFile

  • ファイル名
  • 希望するアクセス (例: GENERIC_READ | GENERIC_WRITE)
  • 共有モード (例: FILE_SHARE_DELETE)
  • オプションで、セキュリティ属性
  • 作成処分 (つまりCREATE_NEWTRUNCATE_EXISTING、など)
  • ファイルまたはデバイスのフラグと属性
  • オプションで、テンプレート ファイル -- ファイルの作成時にその属性をコピーするため

ここで、本当にそうしたくない場合 (ポインター値が必要場合) は、または( C++11 で定義されている可能性reinterpret_castがある) を介してキャストした後にシリアル化してみてください。std::intptr_tstd::uintptr_tcstdint

ar & reinterpret_cast<std::intptr_t>(file);

...次に、これを次のように結合する必要があります(逆シリアル化する場合):

std::intptr_t _file;
ar & _file;
HANDLE file = std::reinterpret_cast<HANDLE>(_file);
于 2012-09-09T21:09:31.667 に答える
0

シリアル化を分割することで問題を解決することになりました。しかし、ハックのようです:

struct Foo
{
    HANDLE file;

protected:
    friend class boost::serialization::access;

    template<class Archive>
    void save(Archive & ar, const unsigned int /*version*/) const
    {
        unsigned int _file = reinterpret_cast<unsigned int>(file);
        ar & _file;
    }

    template<class Archive>
    void load(Archive & ar, const unsigned int /*version*/)
    {
        unsigned int _file;
        ar & _file;
        file = reinterpret_cast<HANDLE>(_file);
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
};
于 2012-09-09T22:44:40.837 に答える