Что такое версия Guid.NewGuid () для C ++? - PullRequest
38 голосов
/ 25 августа 2009

Мне нужно создать GUID в неуправляемом проекте Windows C ++. Я привык к C #, где я бы использовал Guid.NewGuid(). Что такое (неуправляемая версия Windows) C ++?

Ответы [ 5 ]

36 голосов
/ 25 августа 2009

UuidCreate () в Win32 API имеет точно такой же эффект. Однако вам нужно передать адрес переменной, которая получит сгенерированное значение:

UUID newId;
UuidCreate( &newId );

Я считаю, что Guid.NewGuid () просто отображается на него во время выполнения .NET.

33 голосов
/ 25 августа 2009

Я думаю CoCreateGuid - это то, что вы ищете. Пример:

GUID gidReference;
HRESULT hCreateGuid = CoCreateGuid( &gidReference );
14 голосов
/ 11 августа 2012

Вот фрагмент кода для получения результирующего строкового значения сгенерированного GUID:

// For UUID
#include <Rpc.h>
#pragma comment(lib, "Rpcrt4.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    // Create a new uuid
    UUID uuid;
    RPC_STATUS ret_val = ::UuidCreate(&uuid);

    if (ret_val == RPC_S_OK)
    {
        // convert UUID to LPWSTR
        WCHAR* wszUuid = NULL;
        ::UuidToStringW(&uuid, (RPC_WSTR*)&wszUuid);
        if (wszUuid != NULL)
        {
            //TODO: do something with wszUuid

            // free up the allocated string
            ::RpcStringFreeW((RPC_WSTR*)&wszUuid);
            wszUuid = NULL;
        }
        else
        {
            //TODO: uh oh, couldn't convert the GUID to string (a result of not enough free memory)
        }
    }
    else
    {
        //TODO: uh oh, couldn't create the GUID, handle this however you need to
    }

    return 0;
}

Справочник по API:

8 голосов
/ 24 июня 2015

Документация для Guid.NewGuid указывает, как это реализовано:

Это удобный статический метод, который можно вызвать, чтобы получить новый Guid . Метод переносит вызов функции Windows CoCreateGuid .

Итак, нативный эквивалент Guid.NewGuid() равен CoCreateGuide().

<ч /> CoCreateGuid вызывает UuidCreate , чтобы сгенерировать GUID. Оба вызова API немного различаются: хотя UuidCreate возвращает UUID, который гарантированно будет уникальным для компьютера, который его создал, CoCreateGuid создает GUID, который является абсолютно уникальным.

Если вам необходимо решить, какой API использовать, вот соответствующие разделы из документации.

UuidCreate

По соображениям безопасности часто желательно, чтобы адреса Ethernet в сетях не становились доступными вне компании или организации. Функция UuidCreate создает UUID , который невозможно отследить по адресу Ethernet компьютера, на котором он был создан. Он также не может быть связан с другими UUID , созданными на том же компьютере.

CoCreateGuid

Функция CoCreateGuid вызывает функцию RPC UuidCreate , которая создает GUID, глобально уникальное 128-битное целое число. Используйте CoCreateGuid , когда вам нужен абсолютно уникальный номер, который вы будете использовать в качестве постоянного идентификатора в распределенной среде.

6 голосов
/ 23 декабря 2014

Для генерации нового guid в Windows и получения результирующего значения в виде строки.

#include <string>
#include <sstream>
#include <iostream>
#include <windows.h>
#include <iomanip>

int main()
{
    GUID guid;
    CoCreateGuid(&guid);

    std::ostringstream os;
    os << std::hex << std::setw(8) << std::setfill('0') << guid.Data1;
    os << '-';
    os << std::hex << std::setw(4) << std::setfill('0') << guid.Data2;
    os << '-';
    os << std::hex << std::setw(4) << std::setfill('0') << guid.Data3;
    os << '-';
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[0]);
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[1]);
    os << '-';
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[2]);
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[3]);
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[4]);
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[5]);
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[6]);
    os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[7]);

    std::string s(os.str());
    std::cout << s << std::endl;
}

В качестве альтернативы, вы можете использовать sprintf_s для преобразования строки

GUID guid;
CoCreateGuid(&guid);
char guidStr[37];
sprintf_s(
    guidStr,
    "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
    guid.Data1, guid.Data2, guid.Data3,
    guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
    guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
std::string s(guidStr);
...