Переход с 32-битной архитектуры на 64-битную при разработке внешних компонент (ВК) для 1С на языке Delphi часто сопровождается трудностями. Простое переключение целевой платформы в среде разработки в большинстве случаев приводит к тому, что компонента перестает загружаться или вызывает аварийное завершение работы 1С (Access Violation). Разберем по шагам, почему это происходит и как правильно адаптировать код под x64.
Главная проблема кроется в том, как Delphi обрабатывает типы данных при смене платформы. Рассмотрим ключевое различие: в архитектуре x32 указатели (адреса памяти) имеют размер 4 байта, а в x64 — 8 байт. При этом тип Integer в Delphi остается 4-байтовым на обеих платформах.
Внешние компоненты 1С на технологии Native API взаимодействуют с платформой через специальные структуры и таблицы виртуальных методов. Если в этих структурах для хранения адресов функций или объектов использовался тип Integer, то при компиляции под x64 происходит следующее:
Проанализируем структуру TV8ProcRec, которая часто встречается в старых заголовочных файлах v8napi.pas. Именно она отвечает за передачу указателей на функции компоненты в платформу 1С. Для корректной работы в x64 необходимо заменить типы Integer на Pointer или NativeInt в тех местах, где передаются дескрипторы или адреса.
Пример корректного объявления части структуры:
TV8ProcRec = packed record
// ... другие поля ...
Destroy1: Pointer; // Ранее могло быть Integer
Destroy2: Pointer;
Destroy3: Pointer;
// ... другие поля ...
end;
Использование типа Pointer или NativeInt является универсальным решением, так как эти типы автоматически меняют свой размер в зависимости от разрядности компиляции (4 байта для x32 и 8 байт для x64). Это позволяет использовать один и тот же исходный код для обеих платформ.
Рассмотрим ситуацию с методами, которые вызываются платформой 1С. В Native API сигнатуры функций должны строго соответствовать ожиданиям платформы. Обратим внимание на то, что в некоторых версиях интерфейсов количество и тип аргументов могут отличаться. Например, функция выполнения метода CallAsProc или CallAsFunc должна корректно обрабатывать количество параметров.
Посмотрим на пример корректного объявления функции для x64:
function TMyAddInObject.CallAsFunc(const lMethodNum: Integer;
var pvarRetValue: PV8Variant; pvarParams: PV8ParamArray;
const lSizeArray: Integer): Boolean; stdcall;
begin
// Реализация метода
Result := True;
end;
Важно помнить, что в 64-битной Windows директива stdcall по сути игнорируется, так как используется единое соглашение о вызовах Microsoft x64, но ее следует оставлять для совместимости с 32-битной сборкой.
Проанализируем работу со структурой tVariant (в Delphi часто описывается как TV8Variant). Это критически важное место, так как через него передаются все данные между 1С и компонентой. В x64 версии платформы 1С ожидает выравнивания по 8-байтовой границе.
Если вы используете packed record, вы принудительно устанавливаете выравнивание в 1 байт. Для x64 это может быть фатально. Рекомендуется:
{$ALIGN 8} в модулях, описывающих взаимодействие с 1С.tVariant должен составлять 8 байт (для хранения Int64, Double или Pointer).Выясним причину падений при работе со строками или логами, о которых часто упоминают разработчики. При использовании AssignFile или работе с динамическими массивами в x64, любые ошибки в расчете адресов или переполнение типов приведут к Access Violation.
Важные правила:
Integer. Используйте только NativeInt или UIntPtr.IMemoryManager). Его методы также оперируют размерами типа size_t, который в Delphi должен соответствовать NativeUInt.Рассмотрим краткий план действий для успешного перехода на x64:
v8napi.pas или аналог) и замените все типы Integer, предназначенные для хранения адресов и дескрипторов, на Pointer или NativeInt.TV8ProcRec — поля Destroy и указатели на функции обязаны быть 8-байтовыми.try ... except. В 64-битных приложениях необработанные исключения внутри DLL мгновенно завершают работу основного процесса 1С.СистемнаяИнформация.ТипПлатформы).Следуя этим рекомендациям и внимательно следя за размерами типов данных, вы сможете успешно перевести свои наработки на современную 64-битную платформу, обеспечив стабильную работу расширений 1С.