2009-08-25 25 views
32

Necesito crear un GUID en un proyecto de Windows C++ no administrado. Estoy acostumbrado a C#, donde usaría Guid.NewGuid(). ¿Cuál es la versión de C++ (ventanas no administradas)?¿Cuál es la versión de C++ de Guid.NewGuid()?

+0

C++ no define una. Debe confiar en bibliotecas de terceros o API proporcionadas por OS específicas de la plataforma – jalf

Respuesta

27

Creo que CoCreateGuid es lo que buscas. Ejemplo:

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

Llama a UuidCreate() internamente de todos modos. – sharptooth

+1

@sharptooth: Eso es solo la mitad de la verdad. Si bien 'CoCreateGuid' llama a' UuidCreate', proporciona garantías más sólidas con respecto a la exclusividad. [CoCreateGuid] (https://msdn.microsoft.com/en-us/library/ms688568.aspx): * "Use ** CoCreateGuid ** cuando necesite un número absolutamente único que usará como un identificador persistente en un entorno distribuido. "* – IInspectable

+1

¿Necesita una llamada previa a CoInitialize()? –

34

UuidCreate() en Win32 API tiene exactamente el mismo efecto. Sin embargo es necesario pasar una dirección de la variable que recibirá el valor generado:

UUID newId; 
UuidCreate(&newId); 

creo Guid.NewGuid() simplemente mapas en el que dentro del tiempo de ejecución de .NET.

+0

Eso crea una estructura de UUID, no una estructura de GUID. – Simon

+4

Son lo mismo, simplemente nombres typedef diferentes! –

+25

Sí, pero los GUID solo afirman ser únicos en el mundo; ¡Los UUID por reclamo de contrato tienen singularidad Universal! Entonces, si alguna vez quieres que tu código se ejecute en más de un planeta, ¡entonces claramente deberías usar este último! (Desafortunadamente, incluso este último puede resultar insuficiente si/cuando la informática cuántica se activa y la interpretación de muchos universos resulta ser verdadera ...) – BrendanMcK

13

He aquí un fragmento de código para obtener el valor de cadena que resulta del GUID generada: referencia

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

Para generar un nuevo guid en Windows y obtener el valor resultante como una cadena.

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

Como alternativa, se puede usar sprintf_s para la conversión de cadenas

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 documentación para Guid.NewGuid señala, cómo se implementa:

Este es un cómodo método estático que puede llamar para obtener un nuevo Guid. El método envuelve una llamada a la función de Windows CoCreateGuid.

Así que el equivalente nativo a Guid.NewGuid() es CoCreateGuide().


CoCreateGuid llamadas UuidCreate, para generar un GUID. Ambas llamadas API son ligeramente diferentes: aunque UuidCreate devuelve un UUID, que se garantiza que es exclusivo de la computadora que lo creó, CoCreateGuid produce un GUID que es absolutamente único.

Si necesita decidir qué API usar, aquí están las secciones relevantes de la documentación.

UuidCreate:

Por razones de seguridad, a menudo es deseable mantener las direcciones de Ethernet en redes de convertirse en disponible fuera de una empresa u organización. La función UuidCreate genera un UUID que no se puede rastrear a la dirección de Ethernet de la computadora en la que se generó.Tampoco se puede asociar con otros UUID creados en la misma computadora.

CoCreateGuid:

El función CoCreateGuid llama a la función RPC UuidCreate, lo que crea un GUID, un único global entero de 128 bits. Use CoCreateGuid cuando necesite un número absolutamente único que usará como un identificador persistente en un entorno distribuido.

Cuestiones relacionadas