views:

630

answers:

3

I'm trying to get the Global Interface Table by using the following code (Delphi):

uses Comobj, ActiveX;

var
   cGIT : IGlobalInterfaceTable = NIL;
const
   CLSID_StdGlobalInterfaceTable: TGUID = '{00000146-0000-0000-C000-000000000046}';


function GIT : IGlobalInterfaceTable;
begin
   if (cGIT = NIL) then
      OleCheck (CoCreateInstance (CLSID_StdGlobalInterfaceTable, NIL,
                                  CLSCTX_ALL, IGlobalInterfaceTable, cGIT ));
  Result := cGIT;
end;

However, CoCreateInstance throws a "Class Not Registered" exception. And indeed: in HKCR/CLSID there is no entry for {00000146- etc. }.

Which dll or ocx should be registered, to get this definition in the registry? Or am I doing it totally wrong?

+5  A: 

You have defined CLSID_StdGlobalInterfaceTable incorrectly: you have supplied the GUID of the interface rather than a concrete class.

I don't have the Windows header files around, so I can't check against them, but a search suggests it should be:

 CLSID_StdGlobalInterfaceTable: TGUID = '{00000323-0000-0000-C000-000000000046}';
Michael Madsen
This is the definition from ActiveX.pas (delphi source): {$EXTERNALSYM IGlobalInterfaceTable} IGlobalInterfaceTable = interface(IUnknown) ['{00000146-0000-0000-C000-000000000046}'] function RegisterInterfaceInGlobal(const pUnk: IUnknown; const riid: TIID; out dwCookie: DWORD): HResult; stdcall; function RevokeInterfaceFromGlobal(dwCookie: DWORD): HResult; stdcall; function GetInterfaceFromGlobal(dwCookie: DWORD; const riid: TIID; out ppv): HResult; stdcall; end;00000323 is not in the registry
Rocky Luck
Rocky, ActiveX.pas gives the IID of the interface, not the CLSID of the class that implements the interface. You have mis-defined your CLSID constant. Other than that, there's nothing wrong with your code.
Rob Kennedy
My previous comment is not very clear.The last sentence should read:{00000323- etc. } is not in the registry either.
Rocky Luck
Thanks for the answers, Rob. The code stems from a general library I found on the internet. So, that's wrong too. But still I didn't find the GlobalInterfaceTable classID in the registry.
Rocky Luck
Michael: you had the absolute right answer. Thank you!!
Rocky Luck
+2  A: 

Have you used OleView32 to verify the GUID of the class? That utility is available in the Windows SDK and allows you to walk the registry of interfaces much easier than regedit. I would classify the utility as a must have for any COM development.

skamradt
I didn't know about this utility. Now for the $100000 question : which class should I be looking for with this utility. Or how should I search for the IGlobalInterfaceTable class?
Rocky Luck
You can search the interfaces, and I believe once you select one you can select it to dig into a list of who implements that interface. Unfortunately I don't have it on this machine (not doing any com work at the moment) but it does help track down things like what DLL registers the interface, what methods are available, and the ability to walk the inheritance chain.
skamradt
+7  A: 

Here's my unit that does it. I put this together when I was compiling in D2006, but I don't see why it would be any different in D7. I use it for storing an interface to a DCOM server and sharing it between multiple threads.

unit GlobalInterfaceTable;

interface

uses Types,
     ActiveX;

type
  IGlobalInterfaceTable = interface(IUnknown)  
     ['{00000146-0000-0000-C000-000000000046}']  
     function RegisterInterfaceInGlobal (pUnk : IUnknown; const riid: TIID; out dwCookie : DWORD): HResult; stdcall;  
     function RevokeInterfaceFromGlobal (dwCookie: DWORD): HResult; stdcall;  
     function GetInterfaceFromGlobal (dwCookie: DWORD; const riid: TIID; out ppv): HResult; stdcall;  
   end;

  function GIT: IGlobalInterfaceTable;

implementation

uses ComObj;

const
  CLSID_StdGlobalInterfaceTable : TGUID = '{00000323-0000-0000-C000-000000000046}';

function GIT: IGlobalInterfaceTable;  
begin  
  // This function call always returns the singleton instance of the GIT  
  OleCheck(CoCreateInstance (CLSID_StdGlobalInterfaceTable, NIL, CLSCTX_ALL, IGlobalInterfaceTable, Result));  
end;

end.
Conor Boyd
+1 for a complete solution.
skamradt
This is brilliant. I thought the ClassID had to be found in the registry too. But it isn't! Go figure.Thank you for this answer!!
Rocky Luck
You're welcome. To be honest, I think you were nearly there. Rather than analyse all the various bits that everybody had posted, I just thought I'd post the lot that I knew worked. ;-)
Conor Boyd