简体   繁体   中英

Convert a Set of to Integer

As a newbie in Delphi I run into a problem with an external API. This external API expects a parameter with one or two value, I think called bitwise parameter. In Delphi this is done by a set of

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. It may contain one or two TCreateImageTasks. In C++ done by:

__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. That do not look right to me and the external DLL do not know this values.

Where is my fault?

I guess it works when you remove the = 1 in the declaration of TCreateImageTask ?

The = 1 shifts the ordinal values by 1 giving the results you see, but is probably not what is needed. For that we need to know the values for BS_IMGTASK_CREATE and BS_IMGTASK_VERIFY .

My psychic powers tell me that BS_IMGTASK_CREATE = 1 and BS_IMGTASK_VERIFY = 2 . Given that these are bit masks they correspond to the values 2^0 and 2^1 . This matches the ordinal values 0 and 1.

Thus you should declare

TCreateImageTask = (citCreate, citVerify);

to map citCreate to 0 and citVerify to 1.

It's all about something called Bitwise Operation!

Converting a SET to LONGWORD is widely used in Delphi implementation of Windows API.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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