构建C ++ COM对象以生成UUID

时间:2013-03-01 15:17:42

标签: c++ boost com uuid

我需要一个生成GUID的COM对象。我是一名C#开发人员,但这将部署在unix环境中,所以我认为我需要在C ++中构建它。这是我的第一个Visual C ++项目,我在完成它时遇到了一些麻烦。

我采取的步骤:

在Visual Studio中创建了一个新的ATL项目(动态链接库 - 没有其他选项)

右键单击项目 - >添加课程 - > ATL简单对象(短名称:GuidGenerator; ProgID:InfaGuidGenerator)

查看 - > ClassView - > IGuidGenerator - >添加方法(方法名称:生成;参数类型:BSTR * [out];参数名称:retGuid)

添加了Boost以获得与平台无关的UUID生成器。

// GuidGenerator.cpp : Implementation of CGuidGenerator

#include "stdafx.h"
#include "GuidGenerator.h"
#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid.hpp>            // uuid class
#include <boost/uuid/uuid_generators.hpp> // generators
#include <boost/uuid/uuid_io.hpp>         // streaming operators etc.

STDMETHODIMP CGuidGenerator::Generate(BSTR* retGuid)
{
    boost::uuids::uuid uuid = boost::uuids::random_generator()();
    std::string uuidStr = boost::lexical_cast<std::string>(uuid);
    //not really sure what to do from here. 
    //I've tried to convert to BSTR.
    //When I assign the resulting value to retGuid, I often get an error:
    //A value of type BSTR cannot be assigned to an entity of type BSTR*

    return S_OK;
}

有人能为我提供下一步的指导吗?

感谢。


从评论中编辑:

我已经尝试使用以下内容转换为BSTR,但是我收到错误:

STDMETHODIMP CGuidGenerator::Generate(BSTR* retGuid)
{
    boost::uuids::uuid uuid = boost::uuids::random_generator()();
    std::string uuidStr = boost::lexical_cast<std::string>(uuid);

    int wslen = ::MultiByteToWideChar(CP_ACP, 0 /* no flags */,
                                  uuidStr.data(), uuidStr.length(),
                                  NULL, 0);

    BSTR wsdata = ::SysAllocStringLen(NULL, wslen);
    ::MultiByteToWideChar(CP_ACP, 0 /* no flags */,
                      uuidStr.data(), uuidStr.length(),
                      wsdata, wslen);
    retGuid = wsdata;
    //ERROR: A value of type BSTR cannot be assigned to an entity of type BSTR*

    return S_OK;
}

2 个答案:

答案 0 :(得分:1)

假设std::string uuidStr是您想要作为BSTR输出参数返回的字符串,请考虑以下代码:

#include <atlbase.h> // for CComBSTR
#include <atlconv.h> // for CA2W

STDMETHODIMP CGuidGenerator::Generate(BSTR* retGuid)
{
    try
    {
        ....

        // Convert uuidStr from ASCII to Unicode
        CA2W wszUuid( uuidStr.c_str() );

        // Build a COM BSTR from the Unicode string
        CComBSTR bstrUuid( wszUuid );

        // Return the BSTR as output parameter
        *retGuid = bstrUuid.Detach();

        // All right
        return S_OK;
    }
    //
    // Catch exceptions and convert them to HRESULTs,
    // as C++ exceptions can't cross COM module boundaries.
    //
    catch(const CAtlException& ex)
    {
        return static_cast<HRESULT>(ex);
    }
    catch(const std::exception& ex)
    {
        // May log the exception message somewhere...

        return E_FAIL;
    }
}

注意像CA2W这样的RAII帮助程序类如何简化从ASCII到Unicode的转换,CComBSTR简化了原始BSTR的管理。

答案 1 :(得分:0)

这篇关于COM under Unix的微软文章可能会更有帮助。

至于下一步,BSTR不是你通常的字符串; .NET隐藏了这种复杂性。 BSTR是一个专用字符串,旨在跨线程/进程边界进行编组。

查看this answer以了解如何将std :: string转换为BSTR。