Friday, November 9, 2007

User Question: Creating a GUID Programmatically

Yesterday there was a question to my quick tip for creating a GUID in the Delphi IDE asking how to creating a GUID programmatically like this in one's own program. This simple console program demonstrates creating a GUID using the Windows API function CoCreateGuid:


program guid;

{$APPTYPE CONSOLE}

uses
SysUtils, ActiveX;

var
Uid: TGuid;
begin
if CoCreateGuid(Uid) = S_OK then
WriteLn(GuidToString(Uid));
end.


One thing I noticed when writing this example is I didn't need to make a call to CoInitialize. The CoInitialize documentation states "Applications must initialize the COM library before they can call COM library functions other than CoGetMalloc and memory allocation functions." So all Co.* calls must be called after a call to CoInitialize except for CoGetMalloc. Interesting. Does anyone know the answer to this? I suspect the documentation is just wrong.

Update: I changed the code originally posted because I was relying on a unreleased RTL and VCL.

5 comments:

Anonymous said...

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
Uid: TGuid;
Result: HResult;
begin
Result := CreateGuid(Uid);
if Result = S_OK then
WriteLn(GuidToString(Uid))
else
WriteLn('Could not create GUID - Error Code = ', Format('%8.8x', [Integer(Result)]));
ReadLn;
end.

So there is no COM needed as all.

Regards from Germany

Franz-Leo

Chris Bensen said...

Franz-Leo,

CreateGuid calls CoCreateGuid.

Paul-Jan Pauptit said...

You are using ComObj. If you look inside the RTL source, you'll find that it performs the CoInitialize for you inside the unit initialization.

In general, you will not have to bother with CoInitialize inside a Delphi application until you start using COM from within seperate threads.

Hope that helps...

Chris Bensen said...

Paul-Jan Pauptit,

A call CoCreateGuid works even if ComObj is not include. I probably should also mention that I made sure that no calls to CoInitialize are in the program I tested when asking that question. My version of ComObj does not have the call to CoInitialize due to some work I'm doing on the RTL and VCL.

As you stated when using Delphi you generally don't need to call CoInitialize is because many units in Delphi call it for you. They actually shouldn't be doing this and that is something that the Delphi team needs to solve, hence, why I have a modified ComObj.pas on my system.

Paul-Jan Pauptit said...

Ah, thanks for clearing that up. Seems you are right then, looks like the documentation is a bit off there. Wouldn't be too surprised if there were more Co* functions that don't strictly require a CoInitialize(). Perhaps making sure it is called before using COM functionality is more of a 'best practise'.

Post a Comment