我需要一个生成 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/