将Set转换为Integer

时间:2019-06-29 07:58:17

标签: delphi

作为Delphi中的新手,我遇到了外部API的问题。 这个外部API期望一个带有一个或两个值的参数,我认为这称为按位参数。 在Delphi中,这是通过一组

完成的

基本是枚举。

TCreateImageTask = (
  citCreate = 1,
  citVerify
);

我已将其放入一组:

TCreateImageTasks = set of TCreateImageTask

在函数中,我用以下命令填充该集合:

function TfrmMain.GetImageTask: TCreateImageTasks;
begin
    Result:=[];
    if chkCreate.checked then Include(Result, citCreate);
    if chkVerify.checked then Include(Result, citVerify);
end;

现在我必须将此任务交给一个用C ++编写的外部DLL DLL需要一个 __ int8 值。它可能包含一个或两个TCreateImageTasks。在C ++中,通过:

__int8 dwOperation = 0;

   if (this->IsDlgButtonChecked(IDC_CHECK_CREATE))
   {
      dwOperation = BS_IMGTASK_CREATE;
   }

   if (this->IsDlgButtonChecked(IDC_CHECK_VERIFY))
   {
      dwOperation |= BS_IMGTASK_VERIFY;
   }

int32 res = ::CreateImage(cCreateImageParams, dwOperation);

所以我必须将我的一组转换为整数。我这样做

function TfrmMain.SetToInt(const aSet;const Size:integer):integer;
begin
  Result := 0;
  Move(aSet, Result, Size);
end;

我打电话给

current task := GetImageTask;
myvar := SetToInt(currentTask, SizeOf(currentTask));

我现在遇到的问题是,当2个值位于集合中时,myvar为6;如果仅在集合内部创建,则为2;如果仅在集合内部进行验证,则为4。在我看来,这看起来不正确,并且外部DLL不知道此值。

我的错在哪里?

2 个答案:

答案 0 :(得分:1)

我想当您在= 1的声明中删除TCreateImageTask时,它起作用吗?

= 1会将序数值移位1,以给出您看到的结果,但可能不是必需的。为此,我们需要了解BS_IMGTASK_CREATEBS_IMGTASK_VERIFY的值。

我的精神力量告诉我BS_IMGTASK_CREATE = 1BS_IMGTASK_VERIFY = 2。假设这些是位掩码,则它们对应于值2^02^1。这与序数0和1相匹配。

因此您应该声明

TCreateImageTask = (citCreate, citVerify);

citCreate映射到0,将citVerify映射到1。

答案 1 :(得分:0)

这就是所谓的按位运算!

在Windows API的Delphi实现中广泛使用将SET转换为LONGWORD。

这就是您要寻找的:

How to save/load Set of Types?

这里也已经回答了:

Bitwise flags in Delphi