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

标签 c++ boost com uuid

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

我采取的步骤:

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

右键项目->添加类->ATL简单对象(简称:GuidGenerator;ProgID:InfaGuidGenerator)

View -> ClassView -> IGuidGenerator -> 添加方法(方法名:Generate;参数类型: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;
}

最佳答案

假设 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 的管理。

关于c++ - 构建 C++ COM 对象以生成 UUID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15161011/

相关文章:

excel - 如何在 com 自动化中启动特定的 excel 版本?

c++ - 从基础对象继承接口(interface)是一种好习惯吗?

C++11 标准与 CUDA 6.0

c++ - 如何隐藏系统 boost 库?

c++ - 如何覆盖 boost::serialize 获取指向对象的指针时发生的情况

c++ - 方向传感器的 Windows Sensor API C++ COM 集成未在 Windows 10 上定期更新

c# - COM+ 调用远程实例中的方法未知名称错误

c++ - 虚函数题

c++ - 线性链式工厂和 move 语义

c++ - boost Asio : Catching signals without keeping an otherwise finished io_service running