【问题标题】:IDispatch vs OleVariantIDispatch 与 OleVariant
【发布时间】:2016-10-12 02:35:20
【问题描述】:

我从指纹 SDK 中获得了事件 onDone 的示例代码(在注册指纹之后)

procedure TfrmRegister.FPRegisterTemplate1Done(ASender: TObject;
var pTemplate: OleVariant);
var
  l_val : OleVariant;  
  l_pArray : PSafeArray;
  i : integer;
  fpBuffer : PByteArray;
begin
  txtEvtMessage.Caption := 'Done Event Received !!';
  pTemplate.Export(l_val);
  l_pArray := PSafeArray(TVarData(l_val).VArray);
  blobSize := l_pArray.rgsabound[0].cElements * l_pArray.cbElements;
  fpBuffer := VarArrayLock(l_val);

  for i := 0 to blobSize - 1 do
  fpData[i] := fpBuffer[i]; //pvData is byte array

  VarArrayUnlock(l_val);
  mode := 0;
  btnVerify.Enabled := True;
end;

但是当我安装 SDK 并导入类型库时 onDone 的第二个参数是 const pTemplate:IDispatch 而不是 var pTemplate:OleVariant

所以 pTemplate.Export(l_val); 行出现错误,因为 'Undeclared identifier: 'Export'

我根本不懂 ActiveX/OLE/COM 编程。似乎它喜欢旧的帕斯卡代码(PSafeArray、PByteArray 等),并且通过简单的示例和解释很难理解这个术语。

有人知道如何通过一些修改使这些代码正确运行吗? 实际上这些代码适用于 Delphi 6(我使用的是 Delphi 7)

谢谢

【问题讨论】:

  • 这不是旧代码。那只是COM。为什么不尝试学习和理解。
  • @DavidHeffernan 您是否有关于 COM 的链接/文章,带有简单的示例和简单的解释(简单的英语,而不是编程英语)?我找不到它,它们中的大多数都太复杂了。 AFAIK,并不是所有的初学者都容易理解 COM 编程
  • 有些事情很难。如果您不了解 COM,那么任何简单的教程都不会在 2 分钟内改变它。有些事情需要努力。
  • @DavidHeffernan,当然有些东西很难,2 分钟内不会理解。但是如果没有好的解释和好的例子,一切看起来都无法理解。并非所有程序员都是聪明和天才。而且我这里也不是想创建COM,让厂商来处理,我只是想尝试修改代码。

标签: delphi automation delphi-7 fingerprint delphi-6


【解决方案1】:

如果类型库说参数是IDispatch,那么它确实是IDispatch。只需将其分配给本地 OleVariant 变量,然后根据需要使用它,例如:

procedure TfrmRegister.FPRegisterTemplate1Done(ASender: TObject;
  const pTemplate: IDispatch);
var
  l_template, l_val : OleVariant;  
  l_pArray : PSafeArray;
  i : integer;
  fpBuffer : PByteArray;
begin
  txtEvtMessage.Caption := 'Done Event Received !!';

  l_template := pTemplate;
  l_template.Export(l_val);

  l_pArray := PSafeArray(TVarData(l_val).VArray);
  blobSize := l_pArray.rgsabound[0].cElements * l_pArray.cbElements;
  fpBuffer := VarArrayLock(l_val);

  for i := 0 to blobSize - 1 do
    fpData[i] := fpBuffer[i]; //pvData is byte array

  VarArrayUnlock(l_val);
  mode := 0;
  btnVerify.Enabled := True;
end;

【讨论】:

  • 这些代码有效。非常感谢你,雷米。非常感谢
【解决方案2】:

如果你说你能够导入类型库,你应该能够找到哪个接口真正描述了这个Export 方法。如果,那么,你说这个OnDone 事件处理程序有IDispatch 之前是OleVariant,你应该能够将Export 的这个后期绑定调用替换为一个早期绑定调用。例如,如果此接口称为IExporter(以确保您必须与我们共享此 *_TLB.pas 文件或在文档中查找它,如果有的话),则替换:

pTemplate.Export(l_val);

与:

(pTemplate as IExporter).Export(l_val);

【讨论】:

  • 好的。非常感谢您的回答以及有关迟到和早到电话的信息。我还是不明白,但我会尝试找到有关它的文章。
  • 早期绑定在编译时使用静态定义的成员偏移量、vtables 等进行评估,就像普通类一样。后期绑定是在运行时使用IDispatch.GetIDsOfNames()IDispatch.Invoke() 处理的,因此它具有更大的灵活性,但代价是更多的开销。
  • 所以,早期绑定就像普通类一样,在设计时定义成员,后期绑定在运行时定义成员,而不是在设计时。好的,再次感谢雷米。
  • 郑重声明:我对一个关于 Delphi 和 COM 的严肃问题的投票低于零深表遗憾。
猜你喜欢
  • 2013-04-13
  • 2021-09-19
  • 1970-01-01
  • 2013-11-29
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 2014-08-21
  • 2010-12-18
相关资源
最近更新 更多