gpt4 book ai didi

c++ - boost::multi_index_container 与 _com_ptr_t 对象崩溃

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:35 31 4
gpt4 key购买 nike

我尝试将 boost::multi_index_container 与 _com_ptr_t 对象一起使用。代码编译时没有警告,但在运行时崩溃。标准容器(std::setmap 等)与此类对象完美配合。

是否可以将 multi_index_container 与 _com_ptr_t 一起使用?

此处示例代码:

#include "stdafx.h"
#include <boost\multi_index_container.hpp>
#include <boost\multi_index\random_access_index.hpp>
#include <boost\multi_index\global_fun.hpp>
#include <boost\multi_index\ordered_index.hpp>

#import "C:\Windows\SysWOW64\msxml6.dll" exclude("ISequentialStream", "_FILETIME")

using CTest =
boost::multi_index_container<MSXML2::IXMLDOMDocument2Ptr,
boost::multi_index::indexed_by<boost::multi_index::random_access<>>>;


int main()
{
::CoInitialize(nullptr);

CTest tst;

MSXML2::IXMLDOMDocumentPtr doc;
doc.CreateInstance(CLSID_DOMDocument);

tst.push_back(std::move(doc)); <-- crash here

::CoUninitialize();

return 0;
}

最佳答案

  • 我注意到您定义的 multi_index_container 包含 MSXML2::IXMLDOMDocument2Ptr 类型的指针,而 doc 类型MSXML2::IXMLDOMDocumentPtr(没有 2)。我假设这没问题,因为问题实际上与这种差异无关。
  • Boost.MultiIndex does support move semantics ,因此您可以随意使用 std::move
  • 实际问题是 _com_ptr_t 有一个奇怪的、破坏性的 operator& overload返回指向包装接口(interface)的指针。这混淆了 Boost.MultiIndex 的内部代码。您可以按如下方式轻松绕过此重载:

#include <boost\multi_index_container.hpp>
#include <boost\multi_index\random_access_index.hpp>
#include <boost\multi_index\global_fun.hpp>
#include <boost\multi_index\ordered_index.hpp>

#import "C:\Windows\SysWOW64\msxml6.dll" exclude("ISequentialStream", "_FILETIME")

struct IXMLDOMDocument2Ptr:MSXML2::IXMLDOMDocument2Ptr
{
using MSXML2::IXMLDOMDocument2Ptr::IXMLDOMDocument2Ptr;

IXMLDOMDocument2Ptr* operator&(){return this;}
const IXMLDOMDocument2Ptr* operator&()const{return this;}
};

using CTest =
boost::multi_index_container<IXMLDOMDocument2Ptr,
boost::multi_index::indexed_by<boost::multi_index::random_access<>>>;

int main()
{
::CoInitialize(nullptr);
{
// defined in scope so that destruction happens before CoUninitialize
CTest tst;

MSXML2::IXMLDOMDocumentPtr doc;
doc.CreateInstance(CLSID_DOMDocument);

tst.push_back(std::move(doc));
}
::CoUninitialize();

return 0;
}
  • 您介意在 Boost Trac 为这个问题输入一张票吗? ?我可以在内部解决这个问题(不依赖于用户可重载的 operator&),但是我需要一段时间才能找到时间这样做,我不想忘记它。

后记

如果您在整个程序中遇到此问题,您可以按如下方式自动修复:

#include <boost\multi_index_container.hpp>
#include <boost\multi_index\random_access_index.hpp>
#include <boost\multi_index\global_fun.hpp>
#include <boost\multi_index\ordered_index.hpp>

#import "C:\Windows\SysWOW64\msxml6.dll" exclude("ISequentialStream", "_FILETIME")

template<typename CComPtr>
struct CFixedAddressofComPtr:CComPtr
{
using CComPtr::CComPtr;

CFixedAddressofComPtr* operator&(){return this;}
const CFixedAddressofComPtr* operator&()const{return this;}
};

template<typename CComPtr,typename TIndexList>
using CComPtrMultiIndexContainer=boost::multi_index_container<
CFixedAddressofComPtr<CComPtr>,
TIndexList
>;

using CTest =
CComPtrMultiIndexContainer<MSXML2::IXMLDOMDocument2Ptr,
boost::multi_index::indexed_by<boost::multi_index::random_access<>>>;

int main()
{
::CoInitialize(nullptr);

{
// declared in scope so that destruction happens before CoUninitialize.
CTest tst;

MSXML2::IXMLDOMDocumentPtr doc;
doc.CreateInstance(CLSID_DOMDocument);

tst.push_back(std::move(doc));
}

::CoUninitialize();

return 0;
}

关于c++ - boost::multi_index_container 与 _com_ptr_t 对象崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47416304/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com