简体   繁体   English

将Set转换为Integer

[英]Convert a Set of to Integer

As a newbie in Delphi I run into a problem with an external API. 作为Delphi中的新手,我遇到了外部API的问题。 This external API expects a parameter with one or two value, I think called bitwise parameter. 这个外部API期望一个带有一个或两个值的参数,我认为这称为按位参数。 In Delphi this is done by a set of 在Delphi中,这是通过一

The basic is an Enumeration. 基本是枚举。

TCreateImageTask = (
  citCreate = 1,
  citVerify
);

This I have put into a set of: 我将其放入一组:

TCreateImageTasks = set of TCreateImageTask

In a function I fill this set with: 在一个函数中,我用以下命令填充此集合:

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

Now I have to give this Tasks to a external DLL, written in C++ The DLL expects a __int8 value. 现在,我必须将此任务提供给以C ++编写的外部DLL。DLL需要一个__int8值。 It may contain one or two TCreateImageTasks. 它可能包含一个或两个TCreateImageTasks。 In C++ done by: 在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);

So I have to convert my set of to an integer. 所以我必须将我的一组转换为整数。 I do by 我做

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

I call with 我打电话给

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

The problem I have now, that myvar is 6 when 2 values are inside the set, 2 if only create is inside the set and 4 if only verify is inside the set. 我现在遇到的问题是,当2个值位于集合内时,myvar为6;如果仅在集合内创建,则为2;如果仅在集合内进行验证,则为4。 That do not look right to me and the external DLL do not know this values. 这对我来说并不正确,并且外部DLL不知道此值。

Where is my fault? 我的错在哪里

I guess it works when you remove the = 1 in the declaration of TCreateImageTask ? TCreateImageTask您在TCreateImageTask的声明中删除= 1 ,它会TCreateImageTask吗?

The = 1 shifts the ordinal values by 1 giving the results you see, but is probably not what is needed. = 1将序数值移位1,以得到您看到的结果,但可能不是必需的。 For that we need to know the values for BS_IMGTASK_CREATE and BS_IMGTASK_VERIFY . 为此,我们需要知道BS_IMGTASK_CREATEBS_IMGTASK_VERIFY的值。

My psychic powers tell me that BS_IMGTASK_CREATE = 1 and BS_IMGTASK_VERIFY = 2 . 我的精神力量告诉我BS_IMGTASK_CREATE = 1BS_IMGTASK_VERIFY = 2 Given that these are bit masks they correspond to the values 2^0 and 2^1 . 假设这些是位掩码,则它们对应于值2^02^1 This matches the ordinal values 0 and 1. 这与序数值0和1。

Thus you should declare 因此,您应该声明

TCreateImageTask = (citCreate, citVerify);

to map citCreate to 0 and citVerify to 1. 映射citCreate到0和citVerify到1。

It's all about something called Bitwise Operation! 这就是所谓的按位运算!

Converting a SET to LONGWORD is widely used in Delphi implementation of Windows API. 在Windows API的Delphi实现中,将SET转换为LONGWORD已被广泛使用。

This would be what you are looking for: 这就是您要寻找的:

How to save/load Set of Types? 如何保存/加载类型集?

This was already answered here too: 这里也已经回答了:

Bitwise flags in Delphi Delphi中的按位标志

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM