【问题标题】:Delphi 2010: EOleSysError 'Type mismatch' calling ActiveX controlDelphi 2010:EOleSysError 'Type mismatch' 调用 ActiveX 控件
【发布时间】:2012-02-17 17:29:24
【问题描述】:

我有这个 C ActiveX API(没有源代码,只有二进制文件):

// \param a [out] Variant holding a byte array 
// \param b [out] Reference to a longlong (Signed 64-bit)
// \param c [out] Reference to a short
short foo(variant* a, longlong* b, short* c);

在 C# 中运行良好:

//auto-generated import:   
short foo(ref object a, ref long b, ref short c);

test {
 object a=null;
 long b=0;
 short c=0;
 foo(a,b,c); => OK 
}

Delphi 2010 中的 NOK(注意 {??Int64}OleVariant 是由 Delphi 导入工具添加的):

//auto-generated import:
function foo(var a: OleVariant; 
             var b: {??Int64}OleVariant; 
             var c: Smallint): Smallint;

procedure Test;
var
 a, b: OleVariant;
 c: Smallint;
begin
 foo(a,b,c); => **EOleSysError 'Type mismatch' exception**
end;

【问题讨论】:

  • 根据this(netcoole.com/delphi2cs/datatype.htm) long = int64 in Delphi
  • 另外,longlong 是一个有符号的 64 位整数
  • @Dorin C/C++ long 在 Windows 上是 32 位。
  • @David 谢谢,32 位和 64 位编译器都是这样吗?
  • @dorin 是的。这是 windows 和 *nix 之间 C 和 C++ 的关键区别。但我现在看到您的评论与 C# 有关,其中 long 是 64 位。

标签: delphi activex


【解决方案1】:

您可以使用预定义的 WinAPI 类型:

// C definition
short foo(variant* a, longlong* b, short* c);

// Delphi definition
function foo(var a: OleVariant; 
             var b: LongLong; 
             var c: Smallint); Smallint;

procedure FooTest;
var
  a: OleVariant;
  b: LongLong;
  c, RetVal: ShmallInt;
begin
  Retval := foo(a, b, c);
end;

LongLongWindows.pas 中定义,以及许多其他 WinAPI 兼容类型。 (至少它们在 Delphi XE 的 Windows 单元中;由于跨平台和 64 位相关的重定位,XE2 可能已经重定位了其中的一些。)

// Windows.pas definition (Delphi 2010)
type
  LONGLONG = int64;

正如 David 在下面的 cmets 中不断提到的,longlong 不是标准的 C++ 数据类型。但是,根据与您的更新中的参数相关的 cmets,它正是 C++ 开发人员想要的,因此 WinAPI 定义是兼容的(为了文档目的的一致性,保留相同的名称)。

【讨论】:

  • Smallint 是您想要在这里匹配的简短内容。至于longlong,这不是标准的,所以我们必须猜测。
  • LONGLONG 不一定和 longlong 一样。
  • 啊!谢谢,大卫。过于关注longlong。 (它在Windows 单元中的使用时间比Int64 在Delphi 中的使用时间更长,并且被声明为与WinAPI 文档兼容;我认为编写C++ 代码的人也从API 中熟悉它;否则他们可能不会使用它。:) 此外,它用于 C++ ActiveX 库,这意味着必须熟悉 WinAPI 兼容的数据类型。我认为它们兼容的假设是安全的,除非另有证明(因为它不起作用)。
  • 问题是,我不知道 C++ longlong 是什么。你知道它是什么吗?
  • 它在 ActiveX 库中被使用,所以我认为这是一个符合逻辑的猜测(是的,这是一个猜测,但它并不比int64 更多)它是一个 COM 兼容类型。 LONGLONG 至少在ActiveX 单元中的一处使用,因此它显然与COM 兼容。我们在这里劈头发吗? ;)
【解决方案2】:

longlong 不是标准 C++ 类型。我无法从 C++ 代码中判断要使用什么类型。

现在,在我看来,从 C# 中工作更容易,其中类型比 C/C++ 更易于理解和可靠。在 C# 中,long 是有符号的 64 位整数,所以在 Delphi 中 Int64。问题中您的 Delphi sn-p 中的其他两个参数指定正确。

【讨论】:

  • 非常感谢,它使用 Int64 工作。回顾起来似乎很明显,但我没有想到更改导入的 ActiveX 控件,因为它是自动生成的。我想知道为什么它放了一个Variant,也许Delphi被非标准的longlong弄糊涂了?
猜你喜欢
  • 2015-04-13
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 2012-05-18
相关资源
最近更新 更多