Почему не загружается внешняя компонента в 64-битной версии 1С:Предприятие 8.3 и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе на 64-разрядный клиент 1С:Предприятие (впервые появившийся в релизах платформы 8.3.9) разработчики часто сталкиваются с ошибкой: «Ошибка при вызове метода контекста (ЗагрузитьВнешнююКомпоненту): Ошибка при загрузке внешней компоненты». При этом библиотека может успешно регистрироваться в операционной системе через regsvr32, но платформа 1С наотрез отказывается с ней работать. Разберем по шагам, почему возникает эта проблема, какие ограничения накладывает разрядность приложения и как настроить корректное подключение библиотеки.

Причина 1. Устаревший метод ЗагрузитьВнешнююКомпоненту и режим совместимости

Проанализируем механизм вызова. Метод встроенного языка ЗагрузитьВнешнююКомпоненту() является устаревшим механизмом, созданным еще во времена платформ 7.7 и 8.0/8.1 исключительно под 32-разрядную COM-технологию. В 64-битной среде данный метод либо работает некорректно, либо полностью блокируется платформой.

Кроме того, если конфигурация работает в режиме совместимости с устаревшими версиями (например, Версия 8.2.13), платформа ограничивает применение современных механизмов взаимодействия с динамическими библиотеками. Для работы с новыми возможностями 64-битного клиента требуется отключить режим совместимости или поднять его до актуального релиза.

Вместо устаревшего метода необходимо использовать метод ПодключитьВнешнююКомпоненту(). Однако при его вызове важно строго соблюдать синтаксис параметров, иначе функция вернет значение Ложь.

Посмотрим на пример правильного вызова для предварительно зарегистрированной в Windows COM-библиотеки:


// Подключение по ProgID зарегистрированной в реестре компоненты
Если ПодключитьВнешнююКомпоненту("AddIn.MyCustomExtension") Тогда
    ОбъектКомпоненты = Новый ("AddIn.MyCustomExtension");
Иначе
    ВызватьИсключение "Не удалось подключить внешнюю компоненту по ProgID!";
КонецЕсли;

Если же подключение выполняется напрямую из файла DLL без предварительной регистрации в реестре, обязательно указываются тип компоненты и символическое имя:


ПутьКФайлу = "C:\MyComponents\Component64.dll";
СимволическоеИмя = "CustomAddIn";

// Явное указание типа компоненты (COM или Native)
Если ПодключитьВнешнююКомпоненту(ПутьКФайлу, СимволическоеИмя, ТипВнешнейКомпоненты.COM) Тогда
    ОбъектКомпоненты = Новый ("AddIn." + СимволическоеИмя);
Иначе
    ВызватьИсключение "Ошибка подключения внешней компоненты из файла!";
КонецЕсли;

Причина 2. Особенности утилиты regsvr32 в 64-разрядной Windows

Выясним причину частой путаницы при ручной регистрации библиотек через командную строку. В 64-битных версиях Windows системные папки распределены следующим образом:

  1. Каталог C:\Windows\System32 содержит 64-битные системные файлы и утилиты. Вызов regsvr32.exe из этой папки регистрирует 64-разрядную библиотеку в основной ветке системного реестра.
  2. Каталог C:\Windows\SysWOW64 содержит 32-битные системные файлы. Утилита regsvr32.exe оттуда регистрирует 32-разрядные компоненты в изолированной ветке WOW6432Node.

Если 64-битная DLL регистрируется через запуск консоли из SysWOW64, регистрация завершится сбоем либо запишется в неверную ветку, из-за чего 64-битный клиент 1С не сможет обнаружить указанный ProgID. Всегда запускайте регистрацию 64-битных DLL через стандартную командную строку от имени Администратора:

C:\Windows\System32\regsvr32.exe "C:\Path\To\YourComponent64.dll"

Причина 3. Несовпадение структур данных и зависимости при компиляции в Delphi

Рассмотрим технические нюансы компиляции внешней компоненты. Архитектура COM-интерфейсов 1С (таких как IInitDone и ILanguageExtender) опирается на строгие структуры передачи параметров в памяти (например, структуру tVariant). При компиляции под 64-битную платформу в Delphi изменяются соглашения о вызовах (применяется Win64 ABI), размер указателей возрастает с 4 до 8 байт, а также меняется выравнивание полей в памяти.

Если заголовочные файлы Delphi не адаптированы под x64 и не содержат директив строгого выравнивания полей (packed record), адресация методов искажается, в результате чего 1С не может получить интерфейс компоненты при инициализации.

Кроме того, 64-разрядная DLL может иметь внешние зависимости от библиотек среды выполнения. Если в каталогах поиска Windows отсутствуют необходимые 64-разрядные файлы рантайма (пакеты BPL или распространяемые компоненты Visual C++), вызов загрузки библиотеки всегда будет возвращать Ложь.

Практические варианты решения проблемы

Разберем три проверенных способа восстановления работоспособности базы:

  1. Запуск 32-разрядного клиента 1С (наиболее быстрое решение): 64-битный сервер 1С и 64-разрядная ОС Windows без каких-либо ограничений поддерживают работу 32-битного толстого и тонкого клиента 1С. В окне запуска информационных баз перейдите в «Изменить» -> «Настройка...» и принудительно укажите разрядность «32 (x86)». В этом случае вернется полная совместимость с исходной 32-битной версией компоненты.
  2. Перевод внешней компоненты на стандарт Native API: Технология COM для внешних компонент в среде 1С считается устаревшей. Фирма «1С» рекомендует использовать Native API (интерфейс IComponentBase). Компоненты на базе Native API кроссплатформенны, компилируются под любую разрядность и операционную систему, не требуют регистрации в реестре Windows через regsvr32 и бесперебойно работают как в 32-, так и в 64-битных клиентах.
  3. Изоляция 32-битной библиотеки через службу COM+ (Surrogate Process): Если исходного кода компоненты нет и перекомпилировать ее невозможно, 32-битную DLL можно зарегистрировать в оснастке Windows «Службы компонентов» (COM+) как серверное приложение. В таком сценарии библиотека выполняется внутри системного 32-разрядного процесса dllhost.exe, а 64-битный клиент 1С взаимодействует с ней через межпроцессный маршалинг с помощью стандартного конструктора: Объект = Новый COMОбъект("ИмяЗарегистрированногоКласса.ProgID");
← На главную