2009-08-25 18 views
32

Devo creare un GUID in un progetto C++ di Windows non gestito. Sono abituato a C#, dove userei Guid.NewGuid(). Qual è la versione C++ (non gestita da Windows)?Qual è la versione C++ di Guid.NewGuid()?

+0

C++ non ne definisce uno. È necessario affidarsi a librerie di terze parti o API fornite dal sistema operativo specifico della piattaforma – jalf

risposta

27

Penso che CoCreateGuid sia quello che stai cercando. Esempio:

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

chiama comunque UuidCreate() internamente. – sharptooth

+1

@sharptooth: questa è solo metà della verità. Mentre 'CoCreateGuid' chiama' UuidCreate', fornisce maggiori garanzie rispetto all'unicità. [CoCreateGuid] (https://msdn.microsoft.com/en-us/library/ms688568.aspx): * "Utilizza ** CoCreateGuid ** quando è necessario un numero assolutamente univoco che verrà utilizzato come identificativo persistente in un ambiente distribuito. "* – IInspectable

+1

È necessaria una chiamata preventiva a CoInitialize()? –

34

UuidCreate() in API Win32 ha esattamente lo stesso effetto. Tuttavia è necessario passare un indirizzo della variabile che riceverà il valore generato:

UUID newId; 
UuidCreate(&newId); 

credo Guid.NewGuid() semplicemente mappe su di esso all'interno del runtime .NET.

+0

Ciò rende una struttura UUID, non una struttura GUID. – Simon

+4

Sono gli stessi, semplicemente diversi nomi typedef! –

+25

Sì, ma i GUID affermano solo di essere Globalmente univoci; Gli UUID per contratto sostengono di avere unicità universale! Quindi se vuoi che il tuo codice funzioni su più di un pianeta, allora chiaramente dovresti usare quest'ultimo! (Sfortunatamente, anche quest'ultimo potrebbe rivelarsi insufficiente se/quando il calcolo quantistico si attacca e l'interpretazione dei molti universi risulta vera ...) – BrendanMcK

13

Ecco un frammento di codice per ottenere il valore stringa risultante del GUID generato: riferimento

// 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

Per generare un nuovo guid in windows e ottenere il valore risultante come stringa.

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

In alternativa, è possibile utilizzare sprintf_s per la conversione di stringhe

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

La documentazione per Guid.NewGuid sottolinea, come viene implementato:

Questo è un conveniente metodo statico che puoi chiamare per ottenere un nuovo Guid. Il metodo esegue una chiamata alla funzione Windows CoCreateGuid.

Quindi l'equivalente nativo a Guid.NewGuid() è CoCreateGuide().


CoCreateGuid chiamate UuidCreate, per generare un GUID. Entrambe le chiamate API sono leggermente diverse, sebbene: Mentre UuidCreate restituisce un UUID, che è garantito per essere univoco per il computer che lo ha creato, CoCreateGuid produce un GUID che è assolutamente unico.

Se è necessario decidere, quale API utilizzare, qui sono le sezioni pertinenti dalla documentazione.

UuidCreate:

Per motivi di sicurezza, è spesso desiderabile per mantenere indirizzi Ethernet su reti di diventare disponibili al di fuori di una società o organizzazione. La funzione UuidCreate genera un UUID che non può essere tracciato all'indirizzo Ethernet del computer su cui è stato generato.Inoltre, non può essere associato ad altri UUID creati sullo stesso computer.

CoCreateGuid:

La funzione CoCreateGuid chiama la funzione RPC UuidCreate, che crea un GUID, un univoco globale 128 bit intero. Utilizzare CoCreateGuid quando è necessario un numero assolutamente univoco che verrà utilizzato come identificativo persistente in un ambiente distribuito.

Problemi correlati