2

GUID を生成する COM オブジェクトが必要です。私は C# 開発者ですが、これは unix 環境でデプロイされるので、C++ でビルドする必要があると考えています。これは私の最初の Visual C++ プロジェクトであり、完成させるのに苦労しています。

私が取ったステップ:

Visual Studio で新しい ATL プロジェクトを作成しました (ダイナミック リンク ライブラリ - 他のオプションはありません)

プロジェクトを右クリック -> クラスの追加 -> ATL シンプル オブジェクト (短い名前: GuidGenerator; ProgID: InfaGuidGenerator)

View -> ClassView -> IGuidGenerator -> Add Method (メソッド名: Generate; パラメーター タイプ: BSTR* [out]; パラメーター名: retGuid)

プラットフォームに依存しない UUID ジェネレーターを取得する Boost を追加しました。

// 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;
}
4

2 に答える 2

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;
    }
}

のような RAII ヘルパー クラスがCA2W、ASCII から Unicode への変換をCComBSTR簡素化し、rawBSTRの管理を簡素化する方法に注意してください。

于 2013-03-01T16:00:57.917 に答える
0

Unix での COMに関するこの Microsoft の記事は、より一般的に役立つ可能性があります。

次のステップでは、BSTR は通常の文字列ではありません。.NET は、この複雑さを隠します。BSTR は、スレッド/プロセスの境界を越えてマーシャリングされることを目的とした特殊な文字列です。

std::string を BSTR に変換する方法については、この回答をご覧ください。

于 2013-03-01T15:28:25.007 に答える