Как избежать неожиданных конфликтов имен процедур в сервисных программах?
Используя концепции, извлеченные из знаменитой IBM Red Paper об исключениях и обработке ошибок RPG, я написал служебную программу QGPL/ERRFUNC
реализовать многократно используемые функции ошибок, такие как Assert
, Throw
, ThrowMsg
, Rethrow
, а также GetErrorMsg
, Я использовал их в нескольких разных программах, и они работали хорошо.
Только сейчас я использовал Throw
функция в программе RPG ILE, которая также статически вызывает функцию в стиле C access
это используется с потоковыми файлами в файловой системе IFS. Эта программа не будет компилироваться с ошибкой связывания "Определение, предоставленное несколько раз для символа Бросок". Насколько я знаю, при компиляции с использованием CRTBNDRPG
команда, но я смог закомментировать мой H DFTACTGRP(*NO)
спецификации, а затем скомпилировать его, используя CRTRPGMOD
с последующим CRTPGM
с дополнительным параметром DETAIL(*EXTENDED)
, Это распечатывает обширный список всех имен процедур, на которые смотрит компилятор при определении того, с какими процедурами статически связываться. Это выявило двойное определение "броска". Глубоко в 72-страничном листинге IBM предоставляет сервисную программу QJVAJNI
(Java Native Interface), на который есть ссылка, и он содержит экспортированную процедуру, также называемую "Throw".
Теперь самым простым решением для моей непосредственной проблемы было бы просто переименовать мою процедуру "Throw", пересмотреть и перекомпилировать мою сервисную программу, а затем пересмотреть и перекомпилировать все программы, которые ссылаются на нее. Я могу следовать этому решению, но при таком поведении возникает несколько тревожных вопросов:
Почему функция IFS в стиле C использует собственный интерфейс Java для выполнения своей работы? Я вижу импорт сервисных программ, таких как
QC2IFS
а такжеQC2POSIX
это имеет смысл в контексте. Похоже, IBM представила здесь неожиданную зависимость, с которой нам приходится жить. Я уверен, что это одна из сервисных программ C, ссылающаяся наQJVAJNI
потому что, когда я закомментируюaccess
вызов функции,QJVAJNI
не получает ссылки. Возможно, что ссылка наQJVAJNI
Сервисная программа имеет несколько уровней, что означает импорт или импорт.Почему связующее средство так тщательно регенерируется за счет импорта сервисных программ? Связыватель выглядит так, как будто он проходит через каждый импорт, который используется каждой сервисной программой, независимо от того, используется ли этот импорт программой и связанными подпроцедурами. Это необходимо? Не сработает ли рекурсивная проверка только тех импортов, которые используются на каждом уровне? Есть ли способ изменить это поведение?
Если с этими двумя вопросами ничего не поделаешь, значит ли это, что для гарантии того, что привязка будет работать всегда (особенно для "универсальных" функций, таких как обработка ошибок), нужно быть уверенным, что другой экспортируемой процедуры не существует где-нибудь на машине с таким же именем? Я не знаю каких-либо средств, таких как пространства имен, которые могли бы облегчить эту проблему. Насколько я знаю, компиляторы ILE не используют никаких подходов, таких как перегрузка или искажение имен, которые другие платформы могут использовать в этой ситуации. Будет ли хорошей практикой начинать "неформальное пространство имен", как я вижу в некоторых экспортах C (например,
_C_NEU_IFS_feof
) чтобы предотвратить конфликт имен? В качестве альтернативы, есть ли способ найти все экспортированные процедуры на компьютере, чтобы найти нужное имя перед публикацией сервисной программы?Авторы IBM Red Paper являются тяжеловесами в мире программирования ILE. Они назвали один из своих рекомендованных экспортов "Бросок", как я сделал (хотя и с другим списком параметров). Они сталкивались с подобными проблемами? У них был другой способ разрешить конфликт имен?
Я обнаружил, что есть вариант *DUPPROC
можно указать для CRTPGM
, но я не уверен, что это хорошая идея. Документация гласит: "Когда разрешено несколько дублирующих процедур, первой экспортированной процедурой в списке указанных модулей и сервисных программ, которая соответствует запросу на импорт, является выбранная процедура". Можете ли вы быть уверены, какой символ будет первым в списке? Порядок строго определен?
1 ответ
Там нет пространства имен в RPG или C в этом отношении. Когда вы связываете программы ILE, каталог привязки определяет, какие служебные программы (и модули) используются для разрешения имен. Это не каждая сервисная программа в системе. Но есть также некоторые сервисные программы, которые связаны по умолчанию, и если вы используете имя, экспортируемое одной из этих автоматически связанных сервисных программ, у вас будут проблемы с дублирующимися именами. Вы правы, *DUPPROC
плохая идея Единственный способ иметь дело с именами, которые дублируют процедуры в автоматически связанных сервисных программах, - не определять новые процедуры с этими именами. Некоторые люди используют методы псевдо-пространства имен, такие как serviceprogramname_procedurename
или же applicationprefix_procedurename
называя их процедуры. Другие просто удостоверяются, что их процедуры имеют уникальные имена другими способами. Но пока RPG не поддерживает какую-то форму пространства имен, вам придется использовать какую-то произвольную схему именования, чтобы обеспечить уникальность имен процедур.
Кстати, на developerWorks есть RFE для добавления пространств имен в RPG. Вы должны войти в developerworks для ссылки на работу, но вы можете зарегистрироваться бесплатно. Тогда посетите RFE и проголосуйте за него.