如何在Delphi 7中获取GIT?

4

我正在尝试使用以下代码(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;

然而,CoCreateInstance 抛出了一个“类未注册”的异常。实际上,在 HKCR/CLSID 中没有 {00000146- etc. } 的条目。

应该注册哪个 dll 或 ocx,才能在注册表中获得这个定义呢?或者我完全做错了什么?


该函数可正常工作,前提是您使用了以下内容:TGUID = '{00000323-0000-0000-C000-000000000046}'。感谢两位评论者提供的答案。 - Rocky Luck
3个回答

7

这是我的实现代码。我在D2006编译时组装了它,但我认为在D7中也不会有什么不同。我使用它来存储DCOM服务器的接口,并在多个线程之间共享。

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.

太棒了!我以为ClassID也必须在注册表中找到,但实际上不用!真是让人惊喜。非常感谢你的回答! - Rocky Luck
不客气。说实话,我认为你已经接近成功了。与其分析每个人发布的各种细节,我只是想发布我知道可行的全部内容。;-) - Conor Boyd

5

您定义了CLSID_StdGlobalInterfaceTable不正确:您提供的是接口的GUID而不是具体类。

我没有Windows头文件,所以无法对其进行检查,但搜索建议应该是:

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

这是来自ActiveX.pas(Delphi源代码)的定义: {$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不在注册表中。 - Rocky Luck
Rocky,ActiveX.pas 给出了接口的 IID,而不是实现该接口的类的 CLSID。您已经错误地定义了 CLSID 常量。除此之外,您的代码没有任何问题。 - Rob Kennedy
我的上一个评论不是很清楚。 最后一句话应该是: {00000323-等}也没有在注册表中。 - Rocky Luck
感谢你的回答,Rob。这段代码来自我在互联网上找到的一个通用库。所以,那也是错误的。但我仍然没有在注册表中找到GlobalInterfaceTable类ID。 - Rocky Luck

2

你是否使用过OleView32来验证类的GUID?该实用程序可在Windows SDK中获得,并允许您更轻松地遍历接口注册表,而不是使用regedit。我认为这个实用程序对于任何COM开发都是必备的。


我不知道这个工具。现在来到了一个价值100000美元的问题:使用这个工具应该找哪个类?或者我应该如何搜索IGlobalInterfaceTable类? - Rocky Luck
你可以搜索接口,我相信一旦你选择了一个接口,你就可以选择它来查看实现该接口的人员列表。不幸的是,我此时此刻没有这个工具(目前没有做任何com相关的工作),但它确实有助于追踪诸如哪个DLL注册了接口,有哪些可用方法以及遍历继承链的能力等等。 - skamradt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接