Как запустить 32-битную внешнюю компоненту на 64-битной платформе 1С?

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

При работе с торговым оборудованием, особенно со «старым» парком весов или касс, программисты 1С часто сталкиваются с проблемой: производитель предоставляет только 32-битную динамическую библиотеку (DLL), в то время как современная инфраструктура предприятия требует использования 64-битных версий платформы. В этой статье мы подробно разберем, почему возникает эта проблема, какие существуют фундаментальные ограничения и как их можно обойти с помощью различных подходов.

Анализируем причину несовместимости: разрядность и адресное пространство

Для начала выясним причину, по которой 64-битный процесс не может просто так «подцепить» 32-битную библиотеку. Основная проблема кроется в архитектуре операционной системы Windows и способе управления памятью. В 32-битной системе указатель (адрес ячейки памяти) занимает 4 байта, а в 64-битной — 8 байт. Когда 64-битное приложение 1cv8.exe пытается загрузить 32-битную компоненту, возникает конфликт: приложение ожидает, что функции будут возвращать 8-байтовые адреса и данные будут выровнены соответствующим образом, а библиотека работает в 4-байтовом режиме.

Согласно документации MSDN, «A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process». Это означает, что на уровне ядра операционной системы стоит запрет на смешивание кода разной разрядности внутри одного адресного пространства. При попытке принудительной загрузки мы получим ошибку Access Violation или немедленное завершение работы всей платформы.

Почему Native API нельзя «подправить напильником»?

Многие разработчики надеются, что использование технологии Native API в 1С дает больше гибкости. Однако проанализируем ситуацию: Native API подразумевает, что 1С напрямую вызывает экспортируемые функции из DLL. Чтобы 1С смогла работать с компонентой, библиотека должна экспортировать строго определенный набор функций, таких как GetClassNames и GetAppCapabilities.

Если разрядность платформы и DLL не совпадает, таблица экспорта функций оказывается недоступна для вызывающего процесса. В отличие от COM-объектов, которые могут работать через системные «прослойки», Native-компонента должна быть загружена непосредственно в память процесса 1С. Поэтому «обернуть» Native API без написания полноценного внешнего приложения-посредника невозможно.

Рассмотрим типичный пример кода загрузки компоненты, который часто выдает ошибку в смешанной среде:


Попытка
    ЗагрузитьВнешнююКомпоненту("Add1cServerVesy.dll");
    Рез = ПодключитьВнешнююКомпоненту("ОбщийМакет.Макет_1", "ServerAuto", ТипВнешнейКомпоненты.Native);
    Если Не Рез Тогда
        УстановитьВнешнююКомпоненту("ОбщийМакет.Макет_1");
        Сообщить("Требуется перезапуск для установки компоненты!");
        Возврат;
    КонецЕсли;
    Терминал = Новый("AddIn.ServerAuto.Add1CServerVesy");
Исключение
    Сообщить("Ошибка инициализации весов: " + ОписаниеОшибки());
КонецПопытки;

Если этот код выполняется на 64-битном клиенте с 32-битной библиотекой, переменная Рез всегда будет принимать значение Ложь, либо платформа будет аварийно завершаться на этапе вызова Новый.

Решение 1: Использование 32-битного тонкого клиента

Это самый простой и надежный способ, рекомендуемый большинством специалистов. Если у вас сервер 1С работает в 64-битном режиме (что стандартно для ERP или Комплексной автоматизации), это вовсе не обязывает вас использовать 64-битных клиентов на всех рабочих местах.

Разберем алгоритм действий:

  1. На рабочих местах, где физически подключены весы, установите 32-битную версию платформы 1С:Предприятие.
  2. При настройке списка баз в окне запуска укажите использование конкретной версии разрядности (x86).
  3. Поскольку клиентская часть 32-битная, она без проблем загрузит 32-битную DLL весов.
  4. Взаимодействие с сервером (который остается 64-битным) будет происходить через стандартные механизмы 1С, и разрядность здесь не будет играть роли, так как обмен данными идет по сети.

Важный нюанс: если бухгалтер или менеджер работает с тяжелыми отчетами (например, оборотная ведомость по 20 счету за год), 32-битный клиент может вылететь с ошибкой Недостаточно памяти (ограничение в 2-4 ГБ). В этом случае стоит разделить рабочие места: весы подключать на отдельных «легких» терминалах или использовать специализированные обработки.

Решение 2: Использование COM-суррогатов (для COM-компонент)

Если ваша компонента является COM-объектом (а не Native API), вы можете воспользоваться механизмом dllhost.exe в ОС Windows. Это позволяет запустить 32-битную DLL в отдельном системном процессе, с которым 64-битная 1С будет общаться через RPC (Remote Procedure Call).

Проанализируем шаги настройки в Службах компонентов (Component Services):

  1. Создайте новое пустое приложение COM+.
  2. Добавьте в него вашу 32-битную компоненту.
  3. В свойствах приложения на вкладке «Активация» выберите «Серверное приложение».
  4. Теперь Windows будет автоматически запускать 32-битный процесс-суррогат, выступающий мостом.

Для Native API этот метод, к сожалению, неприменим напрямую.

Решение 3: Создание промежуточного звена (Bridge)

Если использование 32-битного клиента невозможно, мы можем применить «напильник» снаружи. Рассмотрим создание небольшого внешнего приложения-посредника. Это приложение (написанное на C#, Delphi или Python x86) будет загружать DLL весов и предоставлять интерфейс для общения с 1С.

Варианты взаимодействия между 64-битной 1С и 32-битной прослойкой:

Рекомендации по выбору стратегии

Проанализировав ситуацию, можно сделать следующие выводы:

1. Если нужно «быстро и бесплатно»: Устанавливаем 32-битный клиент 1С на рабочих местах с весами. Это проверенное решение, которое не требует написания дополнительного кода и поддержки сторонних утилит.

2. Если весы сетевые: Посмотрите, нет ли у производителя драйвера, работающего по протоколу TCP/IP или через Web-интерфейс. Современное оборудование часто вообще не требует установки DLL на клиентский компьютер.

3. Если вы разрабатываете тиражное решение: Имеет смысл написать свою 64-битную компоненту-обертку или полноценный сервис на языке высокого уровня, чтобы избавить пользователей от проблем с разрядностью раз и навсегда.

Помните, что попытки «обмануть» архитектуру процессора внутри одного процесса 1С всегда ведут к нестабильности. Вынос работы с оборудованием за пределы основного процесса — это не только способ решить проблему разрядности, но и хороший тон в архитектуре систем, так как падение драйвера оборудования в этом случае не приведет к потере данных в открытом сеансе 1С.

← На главную