 |
|
 |
Hi, very nice article I just found out, search for something else!
It just happens I've written something similar, with a fall-back code in case the API call fails (for whatever reason):
#include "Rpc.h"
#pragma comment( lib, "Rpcrt4" )
void myClass::CreateGuid(std::string& strGuid)
{
static char szGuidFormat [] = "%08x-%04x-%04x-%04x-%08x%04x";
UUID myUUID;
if (UuidCreate(&myUUID) == RPC_S_OK)
{
UCHAR *pszUuid = 0;
if (UuidToString(&myUUID, &pszUuid) == RPC_S_OK)
{
strGuid = (char*) pszUuid;
RpcStringFree(&pszUuid);
return;
}
}
// fall back in case of failure - build a custom GUID
LARGE_INTEGER cpuTime;
QueryPerformanceCounter(&cpuTime);
long guidValue = crc32::hash((const unsigned char*) &cpuTime, sizeof(cpuTime));
// format is: 65e4dafd-4a1d-4c10-8424-c01dda66b0bc
char szGuid[40];
sprintf_s(szGuid, szGuidFormat,
guidValue,
(guidValue >> 16),
(guidValue & 0xFFFF) ^ (guidValue >> 16),
(long)(cpuTime.HighPart & 0xFFFF),
(long)(cpuTime.QuadPart / 0xF1130495),
GetTickCount() & 0xFFFF
);
strGuid = szGuid;
}
Hope it helps!
|
|
|
|
 |
|
 |
I'm unable to find how to impliment crc32::hash in my code. VC6 and VC9 fail.
--
Chizl
|
|
|
|
 |
|
 |
Hi Joseph.
Any change up updating this article (and your other CodeProject articles) so that links to your useful essays (et al) are up-to-date?
I know where to track them down; but, I'd hate to see someone miss the useful information you've tirelessly made available because get got an error 404.
Keep up the good work.
PeterRitchie.com
|
|
|
|
 |
|
 |
I was not aware that there was a problem...
|
|
|
|
 |
|
 |
If you don't want to link to rpcrt4.lib, you can also format the GUID by using the following piece of code to get a GUID in string form:
GUID guid;
CoCreateGuid(&guid);
CString strGUID;
strGUID.Format("{%.2X-%.2X-%.2X-%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X}", 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]);
Enjoy...
|
|
|
|
 |
|
 |
Doesn't work. Suppose guid.Data2 is 1796 (in decimal). Your CString format will result 704 when it should be 0704.
-- Rubio
|
|
|
|
 |
|
 |
Well, you can use format "02X" and "04X" instead of "2X" and "4X".
|
|
|
|
 |
|
 |
I think the correct format would be:
CString.Format("%.08x-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x",
Remember guid.data1 is unsigned long. This was actually helpful. For the first time in a long, long time I took a good look at correct formatting.
-- Rubio
|
|
|
|
 |
|
 |
Even though VC already did this, this article helped me with a different problem, and that is finding a way to convert strings to and from GUIDs. So don't be afraid to post the "trivial" articles. Nothing is trivial when you can't find that one API function you need.
|
|
|
|
 |
|
 |
Agree with you. This article describes exactly what I need. Thanks again.
|
|
|
|
 |
|
 |
I can join in the thanks. I was looking for a generator for GUIDs and you prodide the solution I was looking for...
|
|
|
|
 |
|
 |
Thanks, I knew there was an API call to generate GUIDs but couldn't think of it. You saved me alot of time.
|
|
|
|
 |
|
 |
Just to let you know if you're using the Microsoft compiler you don't need to use:
#if !defined(DDL_SetExe_449d5a10_7563_11d5_a037_006067718d04)
#define DDL_SetExe_449d5a10_7563_11d5_a037_006067718d04
declarations go here
#endif // DDL_SetExe_449d5a10_7563_11d5_a037_006067718d04
Just "#pragma once" is enough (assuming your using above version 1.x)
|
|
|
|
 |
|
 |
I believe the filename comparisons that #pragma once does are case-sensitive, so if the case of the name in the #include line differs from the name on disk, #pragma once fails to do its job.
(I remember hearing this a while ago, but can't find mention of it on MSDN at the moment. Anyone feel free to correct me if I'm wrong here.)
--Mike--
http://home.inreach.com/mdunn/
"You named the Borg... Hugh?"
-- Guinan
|
|
|
|
 |
|
 |
Not quite. In fact, I just did a test and the answer is "not at all", which suprised me. The truth I believed was that the table created in memory from the #include lines was case sensitive, but you can try this and see that it is no longer case sensitive, if it ever was:
in file b.h:
#pragma once
#pragma message ("b.h included")
in file once.cpp:
// once.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#pragma message("About to include b.h")
#include "b.h"
#pragma message("About to include b.h")
#include "b.h"
#pragma message("About to include B.h")
#include "B.h"
#pragma message("About to include B.h")
#include "B.h"
int main(int argc, char* argv[])
{
return 0;
}
The output is
--------------------Configuration: once - Win32 Debug--------------------
Compiling...
once.cpp
About to include b.h
b.h included
About to include b.h
About to include B.h
About to include B.h
Linking...
once.exe - 0 error(s), 0 warning(s)
Note that if you remove the "#pragma once" you will see "b.h included" four times.
|
|
|
|
 |
|
 |
If you generate a file containing a new Generic class from ClassView, VC takes care of putting in unique directives. Simply create a dummy class just to get the identifier, and then Cut, Copy & Paste!
Sincerely Yours,
Brian Hart
"And that's the news from Lake Wobegon, where all the women are strong, the men are good-looking, and the children are above-average." - Garrison Keillor
|
|
|
|
 |
|
 |
Yes VC already does this. For header files created by VC. That has little to do with this article; in fact, I state
"What I needed was a unique ID for a #define that would keep a header file from being included more than once."
In no way did I suggest that VC was in any way involved in the process of creating the header file. If I were deriving a class using the ClassWizard, this would be true. If I were writing a compiler that, for example, takes a high-level data structure specification and produces a header file and implementation file for an XML-like database schema, VC is not within miles of the generation phase of the header file, and does not help at all.
For that matter, if you just generate a header file in VC, you get a blank file, not one with the #if !defined(...) declaration, so it is not true in general that VC does this; only in the very restricted subcase of header files created for subclasses.
Since other people may need GUIDs for other purposes, or for header files created by their own tools, this seemed a useful technology to make visible.
|
|
|
|
 |
|
 |
I see your point -- this class could be useful. However, to me this functionality seems at first glance like it's rather trivial to add to any program. Can't hurt in saving somebody else the work of trying to figure it out though...
Sincerely Yours,
Brian Hart
"And that's the news from Lake Wobegon, where all the women are strong, the men are good-looking, and the children are above-average." - Garrison Keillor
|
|
|
|
 |
|
 |
Many of these essays are trivial...once you see what to do. But it took me 20 minutes to discover it and implement it, and I *knew* there was an API for GUIDs.
|
|
|
|
 |
|
 |
Good article: still on the theme of whether VC does it already - could you not use:
#pragma once
> Andrew.
|
|
|
|
 |
|
 |
Of course. This, however, assumes that every compiler that might ever be involved in the process implements a Microsoft-specific #pragma, and that every Microsoft compiler is going to be of the latest version that implements it! Hence the need to have the #ifndef/#if !defined() approach. Look at any standard header file produced by ClassWizard:
#if !defined(....)
#define ....
#if _MSC_VER > 1000
#pragma once
#endif
...
#endif
Which is what my database descriptor tool actually puts out...but that has no relevance to the article, so I thought I would not mention the obvious.
|
|
|
|
 |
|
 |
VC7 does not add GUID - based unique directives in class headers anymore. Instead it adds #pragma once.
_________________________________
Get RadVC today. Play RAD in VC++
http://www.capitolsoft.com
|
|
|
|
 |
|
|
 |
|
 |
Visual studio provides a GUID-generating tool, GUIDGEN. This technique illustrates how GUIDs can be generated by a piece of code.
|
|
|
|
 |