GCC - The Complete Reference (537669), страница 48
Текст из файла (страница 48)
Это делает возможной прямую передачу массивов между частями программы, написанными на разных языках. Но следует учесть, что для этих языков отличается порядок индексации многомерных массивов. В Гопгап массивы организованы по столбцам, в то время как в С элементы массивов располагаются построчно. Поэтому при передаче массивов требуется перестановка индексон. Вызов функции С из кода на языке Гог1гап Предлагаемый пример программы на языке гагггап вызывает функцию Си передтст сй строку буквенных знаков и число с плавающей точкой: С И772с.е с РВОВНЬИ Р772С В О)ч)с1 языки гагггап и Смогут использоваться вместе довольно естественно благодаря тому, что между этими языками возможны прямые вызовы функций. Нужно только тщательно учитывать совместимость типов передаваемых аргументов. И тогда написанные на этих языках функции могут использоваться в прямых и в обратных нызовах в точности так же, как если бы они были написаны на одном языке.
В таблице 10.3 перечислены типы С и их соответствия в языке Багггап. Эта таблица применима на многих платформах, но возможны и некоторые исключения. Было бы благоразумно создать небольшую тестовую про)рамму для проверки правильности передачи функциям тех типов, которые вас интересуют. Для этого вполне можно использовать примеры этого раздела. 214 Часть и. Использование Сборного Компилятора СНАВАСТЕВ*32 НЕЬ10 ВЕАЬ Рх НЕЬЬО = "Не11о С Ехоа Рогхгап" НЕЬ1,О(21:21) = СНАВ(0) Р1 = 3.14159 СА11 ЗНОИН1Р1(НЕ1ЬО,Р1) Ех)п РВООВАМ Р772С Переменная неььо типа СНАВАстеВ имеет фиксированную длину в 32 буквенных символа.
В нее запись)вается строка, содержа)цая только 2) символ, после чего оставшаяся часть будет заполнена пробелами. Для преобразования этой строки к такой форме, которая может быть использована в языке С, следует вставить нулевой байт (символ конца строки) после последнего байта, занимаемого записанным в неььО значением. Переменая Р1 типа ВеАь имеет тот же формат, что и тип данных Е1оах языка С, она может прямо передаваться функции С. Важно заметить, что аргументы передаются из кода на языке Рог(гав по ссылке, а не своим значением. Далее приведена функция на языке С, которая выводит на стандартное устройство вывода строку и число, переданные ей из программы на языке Рог(гав: /* вЬоиЬ1р1.с */ №хпс1пае <вха1о.Ь> чо1а вЬоии№р1 (сЬаг *вегхпд,Е1оае *р1) ( рг1пГЕ("Ъв~пр1=ЪЕ1п",вхгхпд,хрх)х ) От одной платформы к другой могут несколько изменяться соглашения об именах и совместимость типов.
Детальнее об этом можно прочитать в документации ОСС. Как видно из примера, в рассматриваемой автором реализации компилятора к имени вызываемой из Рог(гав функции С требуется добавлять символ подчеркивания. Следующие команды скомпилируют оба исходных файла и создадут из них готовую к запуску программу: № д77 -с Е772с.Е -о Е772с.о № дсс -с вЬоиЬ1рг.с -о вЬоиЬ1рх.о 3 д77 с2Е77.о вЬоиЬ1р1.о -о Е772с Вызов из программы на языке С подпрограммы на языке ГогМгап При вызове подпрограммы на языке Рог(гал из программы на С следует форматировать передаваемые строки в соответствии с правилами языка Рог(гав. Следующий пример программы передает строку буквенных символов и число с плавающей точкой: Главе 10.
Совмещение языков 2 1 5 /* с2Е77.с *I кпе ев1п(1пе агдс,сЬаг *агав[)) 1пг 1; Е1оае е = 2.71828) сЬаг Ье11о[32)к Епс 1епдгЬ = вьвеоЕ(Ье11о); вггсру(Ье11о,"Не11о Рогегвп Егоп С")) Еог(1=вгг1еп(Ье11о)) 1<1епдЕЬк 1++) Ье11о[).) = ' ') вЬоиЬ1е (Ье11о,а1епдсв,ае)) геепгп(О)к В программах на языке С длина строки буквенных символов определяется положением нулевого байта — признака копна строки, а в языке Рог(гал строки имеют фиксированную длину. Поэтому необходимо включать в список аргументов число, указывающее действительную длину передаваемой строки.
В этом примере строка записывается в массив СЬаг, который первоначально заполнен нулевыми значениями. Поэтому остальная часть массива Ье11о, состоящего из 32 элементов, заполняется пробелами. Размер массива передается во втором аргументе. Учтите, что в Гог(гал все передаваемые переменные ожидаются как ссылки на их значения, поэтому все аргументы в этом примере передаются указателями. При вызове подпрограммы яа языке Рог(гал обычно требуется добавлять к ее имени символ подчеркивания. Далее приводится исходный код вызываемой подпрограммы (на языке Рог(гав): С вЬоиЬ1е.Е с япваопткме вномн1е(неььо,ьемстн,е) СНАВАСтви*(е) НЕЬЬО 1мтесев ьемстн ВЕАЬ Е Идктв<*,1ОО) НЕЬЬО(1кЬЕМати),ЬЕМати,в 100 РОВМАт(ЗХ,А,2Х,13,4Х,Р6.4) Ветпвм емп впвиопткме вноинке Следующая далее последовательность команд скомпилирует исходники в объектные файлы и затем скомпонует из них готовую к запуску программу с2Е77: 8 д77 -с вЬоиЬ1е.
Е -о вЬоиЬке.о 8 дсс -с с2Е77.с -о с2Е77.о 8 дсс с2Е77.о вЬоимве.о -1Егеьедьп -1д2с -1п -о с2Е77 Третья команда дсс требует наличия библиотек языка Рог(гав. При применении команды д77 необходимые библиотеки подключаются автоматически. Так что последнюю команду можно записать короче: 8 д77 с2Е77.о виоивье.о -о сзЕ77 21б Часть!1. Использование Сборного Компилятора Совмещение языков Ада и С Язык Ада включает в себя встроенные возможности вызова функций на языках С и Гогггал. Это делается применением при объявлении тела процедуры оператора ргадгяа 1спрогс, указывающего внешний язык и имя исходного файла функции. Типы данных, используемые в языках Ада и С вполне совместимы друг с другом.
На это вполне можно рассчитывать, особенно когда объектный код для всех частей программы генерируется компилятором бСС. В таблице 10.4 перечислены идентичные типы для обоих языков. Таблица 10.4. Соответствия типов языков Ае1а и С Тии ивиимк квмкв С Тии ииииии ввмкв Авв Е1оаг Вызов кода С из программы на языке Ада Приведенный далее пример показывает, как тело процедуры в пакете Ада может быть реализовано на языке С.
Следующий листин~ представляет главную программу, вызывающую процедуры Ье11о и доойЬуе из пакета АИа ноийу: Обе процедуры Ье11о и доойЬуе выполняют вывод строки текста, их отличие состоит в том, что доойЬуе написана на Агфа, а Ье11о — на языке С. Участники пакета ноийу определены в файле Ьоийу. айв следующим образом: Далее следует код реализации процедур, включенных в пакет. Файл Ьоийу. айЬ содержит действительный Агфа-код процедуры доойЬуе и объявляет внешнюю реализацию процедуры Ье11о. Г1оаС тпседег ьопд г1оас Ьопд 1пгедег Ьопд Ьопд тпгедег Вьпгг Гспег вЬогс гпседег вЬогс вьогс тпседег -- айв2с.айЬ и1сЬ ноийу; ргосейпге ьйа2С 1в Ьед1п Но йу.ие11ог Ноийу.доойъуе; епй Айа2оз -- Ьоийу.айв раскаде Ноийу ъв ргосейпге не11о; ргосейпге доойЬуег епй Ноийу аопъ1е 1опд 1опд 1опд Ноас еЬогг е1доей сваг Глава 10.
Совмещение языков 2 17 -- Ьонйу.айЬ нхсь тахе хог иве тахе хо; нхгЬ Хпгеггасев.сг Раскаде Ьойу Ноейу хв ргосейиге Не11о хв Ргосейиге вауЬе11о; Ргадта Харогг(С,вауце11о) Ьедхп вауце11ог епй Не11о( Ргосейиге ОоойЬуе хв Ьедхп риг Ь).пе("ОоойЬуе"); епй ОоойЬуе( епй Ноийу( Оператор мхСЬ Хпеегбасев. С используется лля включения совместимости применяемых типов данных с языком С.
Он не является здесь строго необходимым, поскольку вызов функции С не использует аргументов и не возвращает результат. Процедура Ье11о вызывает вауЬе11о — функцию на языке С. Для этого требуется использование операторов ргосейиге и ргадта хороге. Они указывают, что вауЬе11о является внешней функцией на языке С. Первым аргументом оператора ргадша хшрогс является название языка, на котором реализован код тела процедуры. Стандарт А(/а определяет в качестве известлых компилятору языков С ("с"), С++ ("с++"), /сог/гал ("уогсгап") и СОВО(.
("совоь"). Второй аргумент определяет локальное имя, под которым внешняя функция используется в текущей программе. В случае, когда действительное имя внешней функции неприемлемо для использования в программе на языке А(/а, то это внешнее имя указывается в третьем аргументе. Например, вам нужно удаленно вызвать функцию вгргоЬ(), но в программах на языке АЫа имена не должны начиваться знаком подчеркивания. Тогда вы определяете прагму хорога так, чтобы внутрелнее имя всргоЬ указывало на внешнюю функцию всргоЬ; Ргадаа Хороге (С, всргоЬ, " вгргоЬ" ) В примере нашей программы функция на языке С вызывается очень просто, и ее реализация выглядит так: /" вауЬе11о.с */ ()хпс1ийе <всйхо.Ь> чо1й вауЬе11о() ( Ргхпел("не11о С ггош Айа\и")г ) Дальше приводится последовательность команд для компиляции всех исходных фзйлов на языках А(/а и С и для компоновки готовой программы; Л дсс -с вауЬе11о.с -о вауЬе11о.о 3 дсс -с Ьонйу.айЬ 3 дсс -с айа2с.айЬ 3 дпасЬхпй айа2с.а11 ь дпас11пк айа2с.а11 вауЬе11о.о 2 1 8 Часть (1.
Использование Сборного Компилятора Вызов с аргументами функции С из программы на языке Ада Этот пример программы очень похож на предыдущий, только функции, реализованные на языке С, получают аргументы и возвращают значения. В примере используются системные вызовы среды (.) МХ для порождения и остановки процесса, выполняемого в фоновом режиме, (Ьас)(йгоцпд ргосезз). Вот главная программа на языке Аг(а, записанная в файле айавраап.