помогите скомпилировать библиотеку для Winx64

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
yser
новенький
Сообщения: 29
Зарегистрирован: 06.02.2008 10:27:40

помогите скомпилировать библиотеку для Winx64

Сообщение yser »

есть пример библиотеки, нормально компилируется для Win32, но не смог его же скомпилировать для Win64.
не могу понять как исправить, если есть у кого время и возможность помогите.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

yser
"не могу" - какими именно признаками воплощается в окружающую Вас псевдореальность?
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Код: Выделить всё

есть пример библиотеки, нормально компилируется для Win32, но не смог его же скомпилировать для Win64.
не могу понять как исправить, если есть у кого время и возможность помогите.


Какие ошибки выдаёт?
yser
новенький
Сообщения: 29
Зарегистрирован: 06.02.2008 10:27:40

Сообщение yser »

извиняюсь, поспешил и забыл об ошибке написать.

ошибка - Error: Illegal type conversion: "Int64" to "AmiVar"

вот простенький код (набросал на основе примера библиотеки), который компилируется для Win32 и выдает ошибку при компиляции для Win64.

Код: Выделить всё

program project1;

{$mode delphi}

uses  SysUtils;

type
  PSingle = ^Single;
  PSingleArray = ^SingleArray;
  SingleArray = array[0..65535] of Single;

const
  VAR_NONE   = 0;
  VAR_FLOAT  = 1;
  VAR_ARRAY  = 2;
  VAR_STRING = 3;
  VAR_DISP   = 4;

type
  _AmiVar = Int64;
  PAmiVar = ^AmiVar;
  AmiVar = record
    case _type: Integer of
      VAR_FLOAT: (val: Single);
      VAR_ARRAY: (_array: PSingleArray);
      VAR_STRING: (_string: PChar);
      VAR_DISP: (disp: Pointer);
  end;

function test: _AmiVar;
begin
  {Result := AllocArrayResult(); }
  AmiVar(result)._array^[0] := 0;  //   <-- Error: Illegal type conversion: "Int64" to "AmiVar"
end;

begin
  writeln('ok');
end. 
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Не могу сказать с уверенностью, но проблема может быть связана с тем, что результат функции типа Int64 должен быть передан в регистре, а запись в регистре компилятор разместить не может.

Чтобы корректно переписать код, нужно знать как используется функция. Почему функция возвращает _AmiVar, а не сам AmiVar?

Конкретно по приведённому коду: попробуй создать локальную переменную A типа AmiVar, заполнить её, и потом сделать Move(A, Result, SizeOf(Result)).
alexey38
долгожитель
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Сообщение alexey38 »

_AmiVar, т.е. Int64 - 8 байт.
Вы предполагаете, что AmiVar тоже 8 байт, и делаете приведение Int64 к AmiVar.

Но в 64 битной сборке, скорее всего идет выравнивание по 8 байт, соответственно размер AmiVar уже 12 или 16 байт.

Попробуйте либо packed record, либо управление выравниванием.
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

надо либо убрать _type из описания, т.к. он по факту является членом record и увеличивает её sizeof. получится:

Код: Выделить всё

  AmiVar = record
    case Integer of
      VAR_FLOAT: (val: Single);
      VAR_ARRAY: (_array: PSingleArray);
      VAR_STRING: (_string: PChar);
      VAR_DISP: (disp: Pointer);
  end;

либо приводить тип через разименование указателя - компилятор забъет на отличающийся sizeof:

Код: Выделить всё

function test: _AmiVar;
begin
  {Result := AllocArrayResult(); }
  PAmiVar(@result)^._array^[0] := 0;  //   <-- Error: Illegal type conversion: "Int64" to "AmiVar"
end;
Ответить