Преобразовать набор в целое число - PullRequest
0 голосов
/ 29 июня 2019

Будучи новичком в 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;

Теперь я должен передать эту задачу внешней DLL, написанной на C ++. 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));

Проблема, с которой я столкнулся сейчас, заключается в том, что myvar равен 6, когда 2 значения находятся внутри набора, 2, если только create, находятся внутри набора, и 4, если только проверка находятся внутри набора. Мне это не кажется правильным, и внешние библиотеки DLL не знают этих значений.

Где моя вина?

Ответы [ 2 ]

1 голос
/ 29 июня 2019

Я думаю, это работает, когда вы удаляете = 1 в объявлении TCreateImageTask?

= 1 смещает порядковые значения на 1, давая результаты, которые вы видите, но, вероятно, не то, что нужно. Для этого нам нужно знать значения BS_IMGTASK_CREATE и BS_IMGTASK_VERIFY.

Мои психические силы говорят мне, что BS_IMGTASK_CREATE = 1 и BS_IMGTASK_VERIFY = 2. Учитывая, что это битовые маски, они соответствуют значениям 2^0 и 2^1. Это соответствует порядковым значениям 0 и 1.

Таким образом, вы должны объявить

TCreateImageTask = (citCreate, citVerify);

для сопоставления citCreate до 0 и citVerify до 1.

0 голосов
/ 30 июня 2019

Это все о побитовой операции!

Преобразование SET в LONGWORD широко используется в Delphi для реализации Windows API.

Это то, что вы ищете:

Как сохранить / загрузить набор типов?

Здесь уже отвечали:

Побитовые флаги в Delphi

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...