Guid.NewGuid() 的 C++ 版本是什么?

问题描述 投票:0回答:8

我需要在非托管 Windows C++ 项目中创建一个

GUID
。 我习惯了 C#,我会使用
Guid.NewGuid()
。 (非托管 Windows)C++ 版本是什么?

c++ windows winapi guid
8个回答
54
投票

我认为

CoCreateGuid
就是你所追求的。 示例:

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

45
投票
Win32 API 中的

UuidCreate() 具有完全相同的效果。但是,您需要传递将接收生成值的变量的地址:

UUID newId;
UuidCreate( &newId );

我相信 Guid.NewGuid() 只是在 .NET 运行时中映射到它。


18
投票

以下是获取生成的 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参考:


12
投票

Guid.NewGuid的文档指出了它是如何实现的:

这是一个方便的 static 方法,您可以调用它来获取新的 Guid。该方法包装了对 Windows CoCreateGuid 函数的调用。

因此

Guid.NewGuid()
的原生等效项是
CoCreateGuid()


CoCreateGuid 调用UuidCreate,以生成 GUID。不过,这两个 API 调用略有不同:虽然

UuidCreate
返回一个 UUID,并且保证对于创建它的计算机来说是唯一的,但
CoCreateGuid
生成一个绝对唯一的 GUID。

如果您需要决定使用哪个 API,请参阅文档中的相关部分。

Uuid创建

出于安全原因,通常希望防止网络上的以太网地址在公司或组织外部可用。 UuidCreate 函数生成一个 UUID,无法追踪到生成它的计算机的以太网地址。它也不能与同一计算机上创建的其他UUID关联。

CoCreateGuid

CoCreateGuid函数调用RPC函数UuidCreate,它创建一个GUID,一个全局唯一的128位整数。当您需要一个绝对唯一的数字并将其用作分布式环境中的持久标识符时,请使用CoCreateGuid


8
投票
在 Windows 中生成新的 guid 并以字符串形式获取结果值。

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

2
投票
在 Windows 上获取 std::string 中的 guid

#include <Windows.h> #include <array> std::string getGUID() { std::string result{}; GUID guid; if (S_OK == CoCreateGuid(&guid)) { std::array<char, 36> buffer{}; //32 characters of guid + 4 '-' in-between snprintf(buffer.data(), buffer.size(), "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", 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]); result = std::string(buffer.data()); } return result; }
    

1
投票
在新的 WinRT api 中,您可以使用

winrt::Windows::Foundation::GuidHelper::CreateNewGuid()

 它返回 
winrt::guid
 类型的结构。您稍后可以将其传递给 
winrt::to_hstring
 来获取 
winrt::hstring
 类型的结构体,然后将其传递给 
winrt::to_string
 来获取 
std::string
 类型。


0
投票
当前

CoCreateGUID

combase.dll
 的实现所做的就是调用 
UuidCreate
,如果结果是 
RPC_S_UUID_LOCAL_ONLY
,则将其替换为 
S_OK

#include <rpc.h> #pragma comment(lib, "rpcrt4.lib") static const int uuid_string_length = 36; HRESULT CreateGUID(std::string& GUID) { UUID uuid = { 0 }; RPC_CSTR uuid_string = nullptr; HRESULT hr = UuidCreate(&uuid); hr = (hr == RPC_S_UUID_LOCAL_ONLY) ? S_OK : hr; if (SUCCEEDED(hr)) { hr = UuidToStringA(&uuid, &uuid_string); } if (SUCCEEDED(hr)) { GUID.resize(uuid_string_length); memcpy(&GUID[0], uuid_string, uuid_string_length); } if (uuid_string != nullptr) { RpcStringFreeA(&uuid_string); } return hr; }
这是正确的做法,因为 GUID 不如 UUID 唯一。

© www.soinside.com 2019 - 2024. All rights reserved.