Ошибки в наименованиях методов в 1c++

Автор alyuev, Сегодня в 15:00

« назад - далее »

alyuev

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

Ниже ошибочная буква выделена красным.

1. ЗаменитьБазовыйОбъект / ReplaceBaseObject (стандартный метод КОП)

  • Где: Source\UserClassesImpl.cpp, строка 1676:
defFnNames->AddParam("ReplaсeBaseObject", "ЗаменитьБазовыйОбъект", ...)

  • Ошибка в 6-й букве, первая «c» сразу после Repla: ReplaсeBaseObject — эта «с» русская. Вторая «c» (в слове Object) латинская, с ней всё в порядке.
  • Что не работает: ReplaceBaseObject(...), набранное латиницей, выдаёт «Метод не найден».
  • Что работает:
  • русское имя ЗаменитьБазовыйОбъект(...);
  • старый синоним ЗаменитьЭксзБазовогоКласса / ReplaceInstBaseClasses. Он помечен как устаревший, но имена у него корректные.
[/list]

2. СнятьПерехватСобытийГК / UnHookEventsOfGroupContext (класс Перехватчик / Hooker)

  • Где: Source\System\Hooker.cpp, строка 26:
BL_METH_PROC("UnHookEventsOfGroupContext", "СнятьПерехватСобытийГK", ...)

  • Ошибка в последней букве: СнятьПерехватСобытийГK — эта «K» латинская.
  • Что не работает: Перехватчик.СнятьПерехватСобытийГК(...) с русской «К» выдаёт «Метод не найден». Парный метод ПерехватитьСобытияГК написан правильно, поэтому ошибиться очень легко.
  • Что работает: английское имя UnHookEventsOfGroupContext(...).
  • Та же латинская «K» стоит в тексте сообщения об ошибке (Hooker.cpp, строка 120). Это только косметика.

Как обойти сейчас, не пересобирая компоненту

  • Вместо ReplaceBaseObject пишите ЗаменитьБазовыйОбъект.
  • Вместо СнятьПерехватСобытийГК пишите UnHookEventsOfGroupContext.
  • Если имя скопировано из старой документации (Hooker.rst, history.txt) или из юнит-тестов 1С++, оно может содержать ту же «неправильную» букву. Тогда вызов работает, но только до исправления компоненты. Лучше сразу перейти на варианты выше: они работают в любой версии.

Как исправить в исходниках (предложение)

Правильное имя нужно добавить, а ошибочное оставить синонимом, чтобы не сломать уже написанный код:

// UserClassesImpl.cpp
defFnNames->AddParam("ReplaceBaseObject", "ЗаменитьБазовыйОбъект", funcReplaceInstBaseClasses, 1, 2);  // латинская c
// + синоним с прежним (ошибочным) написанием "Repla\xF1eBaseObject" для совместимости

// System\Hooker.cpp
BL_METH_PROC("UnHookEventsOfGroupContext", "СнятьПерехватСобытийГК", 1, &procUnHookEventsOfGroupContext) // русская К
// + синоним с прежним написанием "СнятьПерехватСобытийГK" (латинская K)

Перед правкой стоит проверить, что карта методов допускает два имени для одного номера метода. Если не допускает, синоним оформляется отдельной записью с тем же обработчиком: так в 1С++ уже сделано для ЗаменитьЭксзБазовогоКласса.

Как это нашли

Скриптом проверили все строковые литералы исходников 1С++ на слова, где смешаны кириллица и латиница из похожих букв (А/A, С/C, К/K, О/O, Р/P и т.д.). Кроме этих двух методов нашлось одно сообщение об ошибке: SQL\MetaDataWork.cpp, строка 414, «Cписок значений...», где первая буква «C» латинская (косметика). Всё остальное оказалось в комментариях. Такие имена, как ВыполнитьSQL_ИзТЗ, РежимRPC, СоздатьALS, смешаны намеренно и проблемой не являются.