本文介绍了Delphi枚举变量为varInteger而不是varUInt32的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Delphi枚举值本机定义为无符号整数-1、2或4个字节,具体取决于MINENUMSIZE的设置.

Delphi enumeration values are natively defined as unsigned integers - 1, 2 or 4 bytes, depending on the setting of MINENUMSIZE.

我有一种情况,我们使用Variant在应用程序之间传输不同数据类型的数据.所有其他数据类型都能很好地工作,但是现在我们意识到,来自其他应用程序的期望是枚举值应该是带符号的整数,而不是无符号的(有些确实在对此进行验证).

I have a case where we are using Variants to transfer data of different data types between applications. All other data types work nicely, but now we realised that the expectation from other applications is that the enumerated values should be signed integers instead of unsigned (and some are really validating this).

是否有一种方法可以配置自动变量转换,以将枚举值转换为varInteger而不是varUInt32?

Is there a way to configure the automatic variant conversion that the enumeration values would be converted to varInteger, instead of varUInt32?

背景:我们正在为OPC UA编写库代码. OPC UA定义了一种称为Variant的类型,该类型在Windows Variant中具有历史记录,但是现在以不同的方式进行了定义.实际上,OPC UA定义枚举值通过网络传输为Int32.

The background: we are writing library code for OPC UA. OPC UA defines a type called Variant, which has history in Windows Variant, but is now defined in a different way. In practice, OPC UA defines that enumeration values are transferred as Int32 over the wire.

OPC UA还定义了一种称为DataValue的数据类型,该数据类型由Value(作为变量),StatusCode(UInt32)和一些Timestamp字段组成.

OPC UA also defines a data type called DataValue, which consists of the Value (as Variant), StatusCode (UInt32) and some Timestamp fields.

现在,我们正在使用Delphi Variants映射OPC UA Variant,因为它通常可以很好地工作.现在唯一的主要陷阱是,当您将一个枚举值写入Variant时,它会转换为UInt32,而OPC UA则期望Int32.

Now, we are using Delphi Variants for mapping the OPC UA Variant, since it works nicely in general. Now the only major pitfall is that when you write an enumeration value to the Variant it is converted to UInt32, whereas OPC UA expects Int32.

该库采用Variants(在DataValues中),作为应用程序开发人员,您只需将枚举值分配给DataValue,一切看起来就很好.但是,该值已转换为UInt32,并且当库代码看到此Variant时,它不再知道它实际上与变量的枚举类型相对应.

The library takes in Variants (in DataValues) and as an application developer, you can just assign your enumeration values to the DataValue and everything looks good. However, the value has been converted to an UInt32 and when the library code sees this Variant it cannot know anymore that it corresponds actually to an enumeration type of variable.

我们应该能够控制自动转换(或者实际上是枚举的本机数据类型),就可以解决这个问题.

Should we be able to control the automatic conversion (or actually the native data type of enumerations), we could simply get rid of this problem with that.

如果这是不可能的,那么我们将真的必须在任何可能的地方发明转换代码,但毕竟不可能永远100%确定.

If that is not possible, we will really have to invent conversion code, wherever we can, but which can never be 100% certain, after all.

推荐答案

您无法区分将枚举类型分配给变量,还是将整数类型分配给变量.考虑以下代码:

You can't distinguish between assignment of enumerated type to variant, and assignment of integer type to variant. Consider the following code:

uses
  System.SysUtils;

type
  TFoo = (foo, bar);

var
  V: Variant;
  enum: TFoo;
  b: Byte;

begin
  V := enum;
  V := b;
end.

编译器生成以下内容:


Project52946989.dpr.14: V := enum;
00422562 B8389F4200       mov eax,$00429f38
00422567 33D2             xor edx,edx
00422569 8A15489F4200     mov dl,[$00429f48]
0042256F B101             mov cl,$01
00422571 E8BED1FFFF       call @VarFromInt
Project52946989.dpr.15: V := b;
00422576 B8389F4200       mov eax,$00429f38
0042257B 33D2             xor edx,edx
0042257D 8A15499F4200     mov dl,[$00429f49]
00422583 B101             mov cl,$01
00422585 E8AAD1FFFF       call @VarFromInt

因此,即使您钩住处理此类赋值的库例程(System.Variants._VarFromInt),也不可避免地会选择Byte值以及枚举类型值的赋值.

So even if you hook the library routine that handles such an assignment (System.Variants._VarFromInt), you will inevitably pick up assignments of Byte values as well as enumerated type values.

上面的代码假定单字节枚举类型的大小,但是对于2或4字节枚举类型没有太大变化.代替看起来像字节分配的分配,它看起来像分别是WordLongWord分配.

The above code assumes single byte enumerated type size, but nothing much changes for 2 or 4 byte enumerated types. Instead of the assignment looking like a byte assignment it looks like a Word or LongWord assignment, respectively.

这篇关于Delphi枚举变量为varInteger而不是varUInt32的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 09:28