Как преобразовать LPARAM в структуру в Delphi?

#delphi

#delphi

Вопрос:

Мне нужна помощь, чтобы привести LPARAM тип к структуре. Например, в C мы имеем:

 struct MyStructure
{
   int data01;
   int data02;
};

BOOL CALLBACK CallbackProc(int number, LPARAM param)
{
   MyStructure *myStruct = (MyStructure *) param;
}
  

И в Delphi я попробовал это, но компилятор выдает ошибку несовместимых типов в выделенной строке с комментарием:

 type
  TMyStructure = record
    data01: Integer;
    data02: Integer;
  end;

PMyStructure = ^TMyStructure;

function CallbackProc(number: Integer; param: LPARAM): BOOL; stdcall;
var
  myStruct: TMyStructure;
begin
  myStruct := param; // How stays here?
end;
  

Комментарии:

1. Это указатель на структуру. Приведите его к PMyStructure.

2. Но как? myStruct := (PMyStructure)param не работает.

3. Конечно, нет. Вы не можете присвоить указатель на T переменной типа T. Вам нужно разыменовать указатель, используя ^ оператор. Я предлагаю вам освежить в памяти синтаксис указателя в документации.

4.docwiki.embarcadero.com/RADStudio/en/… docwiki.embarcadero.com/RADStudio/en/…

Ответ №1:

Код C преобразует LPARAM в указатель на структуру. В Delphi это выглядело бы примерно так:

 type
  TMyStructure = record
    data01: Integer;
    data02: Integer;
  end;
  PMyStructure = ^TMyStructure;

function CallbackProc(number: Integer; param: LPARAM): BOOL; stdcall;
var
  myStruct: PMyStructure;
begin
  myStruct := PMyStructure(param);
end;
  

Комментарии:

1. Или: var myStruct: TMyStructure; begin myStruct := PMyStructure(LPARAM)^; end; .

2. @RudyVelthuis да, но это создает копию данных структуры, тогда как использование указателя позволяет вам работать с исходными данными напрямую.

3. иногда требуется копия.

4.@RemyLebeau, что правильно для доступа к каждому элементу структуры на основе вашего решения? таким образом: myStruct.data01 и myStruct.data02 ИЛИ myStruct^.data01 и myStruct^.data02 ? В чем разница между . и ^. ?

5. @BrowJr в Delphi, когда включен расширенный синтаксис (который включен по умолчанию), компилятор принимает оба синтаксиса при обращении к элементу через указатель. ^ Для разыменования указателя необязательно. Итак, оба способа верны, разницы нет. Компилятор выдает один и тот же машинный код в обоих случаях.