2009-08-25 4 views
32

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

+0

C++ не определяет один. Вы должны полагаться на сторонние библиотеки или специфичные для платформы API-интерфейсы, поддерживаемые ОС – jalf

ответ

27

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

GUID gidReference; 
HRESULT hCreateGuid = CoCreateGuid(&gidReference); 
+9

В любом случае он вызывает UuidCreate(). – sharptooth

+1

@sharptooth: Это только половина правды. Хотя 'CoCreateGuid' действительно вызывает' UuidCreate', он обеспечивает более надежные гарантии в отношении уникальности. [CoCreateGuid] (https://msdn.microsoft.com/en-us/library/ms688568.aspx): * «Использовать ** CoCreateGuid **, когда вам нужен абсолютно уникальный номер, который вы будете использовать в качестве постоянного идентификатора в распределенной среде. "* – IInspectable

+1

Нужен ли предварительный вызов CoInitialize()? –

34

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

UUID newId; 
UuidCreate(&newId); 

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

+0

Это делает структуру UUID, а не структуру GUID. – Simon

+4

Они такие же, просто разные имена typedef! –

+25

Да, но GUID только утверждают, что являются глобально уникальными; UUID по контракту претендуют на универсальную уникальность! Поэтому, если вы когда-нибудь захотите, чтобы ваш код работал на более чем одной планете, тогда вы должны использовать последний! (К сожалению, даже последнее может оказаться недостаточным, если/когда квантовые вычисления улавливаются, и интерпретация многих вселенных оказывается верной ...) – BrendanMcK

13

Вот фрагмент кода, чтобы получить результирующую строковое значение генерируемого 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:

4

Чтобы создать новый указатель в окнах и получить результирующее значение в виде строки.

#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); 
7

Документация 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, когда вам нужен абсолютно уникальный номер, который вы будете использовать в качестве постоянного идентификатора в распределенной среде.

Смежные вопросы