gpt4 book ai didi

delphi - 具有相同 GUID 的两个接口(interface)的相关性交互是什么

转载 作者:行者123 更新时间:2023-12-03 15:30:46 24 4
gpt4 key购买 nike

我曾经认为 Delphi 中关于接口(interface)的类型安全是通过为其设置唯一的(可选,但如果填写则唯一)GUID 来维护的。

然后就出现了这个问题:Unspecified error when calling Word CentimetersToPoints via OLE
后续行动很少:http://pastebin.ca/2369858

我开始寻找库存的 Delphi TWordApplication 组件(即 Word200.pas 单元)。我在那里看到:

// *********************************************************************//
// Interface: _Application
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {00020970-0000-0000-C000-000000000046}
// *********************************************************************//
_Application = interface(IDispatch)
['{00020970-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; safecall;



// *********************************************************************//
// DispIntf: _ApplicationDisp
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {00020970-0000-0000-C000-000000000046}
// *********************************************************************//
_ApplicationDisp = dispinterface
['{00020970-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; dispid 371;

或类似:

// *********************************************************************//
// Interface: _Global
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {000209B9-0000-0000-C000-000000000046}
// *********************************************************************//
_Global = interface(IDispatch)
['{000209B9-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; safecall;

// *********************************************************************//
// DispIntf: _GlobalDisp
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {000209B9-0000-0000-C000-000000000046}
// *********************************************************************//
_GlobalDisp = dispinterface
['{000209B9-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; dispid 371;

我在这里感到完全迷失了。

我曾经认为 dispinterfaceinterface 的“子类”,就像 TPercientTObject 一样?如果是,那么同一个项目中怎么可能有两个具有相同 GUID 的接口(interface)?

或者它们来自不同的不相关框架,例如 Delphi 新的 class 类型到继承的 TurboPascal object 类型? _GlobalDisp_ApplicationDisp 似乎都没有在 Word200.pas 中使用,所以它们就像附录一样,自动导入但从未实际使用过?

我使用 _Application_ApplicationDisp 创建了该项目,并且可以编译。但我只是想知道如果它们具有相同的 GUID,Delphi 是如何对其进行类型转换的?

procedure TForm4.Button1Click(Sender: TObject);
procedure show(const s: Single);
begin
ShowMessage(FloatToStr(s));
end;
begin
show( WordApplication1.CentimetersToPoints(1.0) );
show( WordApplication1.Application.CentimetersToPoints(2.0) );
show( WordApplication1.DefaultInterface.CentimetersToPoints(3.0) );
show( _ApplicationDisp(WordApplication1.Application).CentimetersToPoints(4.0) );
show( (WordApplication1.DefaultInterface as _ApplicationDisp).CentimetersToPoints(5.0) );
end;

最佳答案

dispinterface 实际上只是将 IDispatch 用于自动化接口(interface)的一种便捷方式。这就是为什么它们具有相同的 GUID – 它们在幕后是完全相同的。

当您使用IDispatch 调用方法时,您通常必须调用GetIdsOfNames 来获取方法的调度ID。但由于这些是静态的,如果您知道调度 ID,则可以跳过该步骤来节省时间。这就是 dispinterface 允许您做的事情。

当您在 dispinterface 上调用方法时,您最终仍然会在 IDispatch 上调用 Invoke,但会跳过对 的调用>GetIdsOfNames

当您将QueryInterface与接口(interface)一起使用时,您将获得IDispatch。然后,您可以将其转换为相应的dispinterface。它仍然是相同的接口(interface),但是当您调用 dispinterface 上的方法时,您将将该调用保存到 GetIdsOfNames

因此,如果您有一个用于 Word 应用程序对象的 IDispatch,例如,您可以编写如下代码:

var
WordApp: Variant;
WordDisp: _ApplicationDisp;
....
WordApp := CreateOleObject('Word.Application');
WordDisp := _ApplicationDisp(IDispatch(WordApp));

_ApplicationDisp() 转换只不过是对 IntfCopy 的调用。这只不过是对 _AddRef 的调用。然后你可以写:

Writeln(WordApp.ProductCode);
Writeln(WordDisp.ProductCode);

两者产生相同的输出。前者在调用 Invoke 之前首先调用 GetIdsOfNames。后者直接进入Invoke

关于delphi - 具有相同 GUID 的两个接口(interface)的相关性交互是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16295132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com