Показаны сообщения с ярлыком gcc. Показать все сообщения
Показаны сообщения с ярлыком gcc. Показать все сообщения

суббота, 26 января 2013 г.

Cовместное использование языков Си и Фортран.

В UNIX системах языки Си и Фортран могут использоваться вместе, так как между этими языками возможны прямые вызовы функций. При этом, правда, необходимо тщательно учитывать совместимость типов передаваемых аргументов. Обычно соответствие между типами в Си и Фортране можно представить так:
signed char    INTEGER*1
short               INTEGER*2
int                   INTEGER
long                INTEGER*4
float                REAL
double            DOUBLE PRECISION
void sub_        SUBROUTINE SUB()
float  fun_()     REAL FUNCTION FUN
Также следует помнить о следующем: 
  • в Фортране аргументы в функции всегда передаются ссылками;
  • В Си массивы передаются через адрес;
  • Порядок индексации многомерных массивов различен для Си и Фортрана - в Си элементы массива располагаются построчно, в Фортране - по столбцам;
  • Имена функций в Фортране имеют в своем конце "скрытый" знак подчеркивания '_' (его нет в исходном тексте, но он добавляется компилятором), поэтому, если некая фунция вызывается из Фортрана как fun(), то эта же функция из Си вызывается как fun_() ; 
  • В языке Си длина строки определяется положением нулевого байта, в Фортране же строки имеют фиксированную длину. Поэтому при передаче строки из Си кода в Фортран необходимо передавать также ее длину. В случае же передачи строки из Фортран кода в Си необходимо добавить нуль в конец строки;
Рассмотрим два случая: когда си код вызывается из фортрана и , наоборот, когда из фортран кода вызывается си код.
Файл cCode1.c:
#include<stdio.h>
void
c_function_(){
     printf("Hello from C code!\n");
}
 Файл fortranCode1.f90:
program hello
    implicit none
    call c_function()
    write (*,*)"Hello from FORTRAN code!"
end program hello
 Компилируем и запускаем на выполнение:
#gfortran -O2 -g -o fortranCode1.o -c fortranCode1.f90
#gcc -O2 -g -o cCode1.o -c cCode1.c
#gcc -L /usr/lib/gcc/i486-linux-gnu/4.7/ -lgfortran fortranCode1.o cCode1.o -o hello1
#./hello1
Нужно, чтобы присутствовала библиотека libgfortran.so
 /usr/lib/gcc/i486-linux-gnu/4.7/ - это путь, по которомуона у меня лежит. У вас может быть другой путь.
Обратный случай:
Файл cCode2.c:
#include<stdio.h>
void
main(){
     fortran_function_();
     printf("Hello from C code!\n");
Файл fortranCode2.f90:
subroutine fortran_function
    implicit none
    write (*,*)"Hello from FORTRAN code!"
end subroutine fortran_function
Компилируем и запускаем на выполнение:
#gfortran -O2 -g -o fortranCode2.o -c fortranCode2.f90
#gcc -O2 -g -o cCode2.o -c cCode2.c
#gcc -L /usr/lib/gcc/i486-linux-gnu/4.7/ -lgfortran fortranCode2.o cCode2.o -o hello2
#./hello2
Теперь сделаем вызов функции с передачей параметров разных типов.
Файл cCode3.c:
#include<stdio.h>
void
c_function_(signed char* a1, short* a2, int* a3, long int* a4){
     printf("in called c function: \n%d\t%d\t%d\t%ld\n", *a1, *a2, *a3, *a4);
}
 Файл fortranCode3.f90:
program hello
    implicit none
    integer*1 a1
    integer*2 a2
    integer*4 a3
    integer*8 a4
    a1=1
    a2=22
    a3=333
    a4=4444
    call c_function(a1, a2, a3, a4)
end program hello
 #gfortran -O2 -g -o fortranCode3.o -c fortranCode3.f90
#gcc -O2 -g -o cCode3.o -c cCode3.c
#gcc -L /usr/lib/gcc/i486-linux-gnu/4.7/ -lgfortran fortranCode3.o cCode3.o -o hello3
#./hello3
 Файл cCode4.c:
#include<stdio.h>
void
main(){
     signed char a1 = 1;
     short            a2 = 22;
     int                 a3 = 333;
     long              a4 = 4444;
     fortran_function_(&a1, &a2, &a3, &a4);
Файл fortranCode4.f90:
subroutine fortran_function(f1, f2, f3, f4)
    implicit none
    integer*1 f1
    integer*2 f2
    integer*4 f3
    integer*4 f4
    write (*,100)f1,f2,f3,f4
100 format(4i5)
end subroutine fortran_function
#gfortran -O2 -g -o fortranCode4.o -c fortranCode4.f90
#gcc -O2 -g -o cCode4.o -c cCode4.c
#gcc -L /usr/lib/gcc/i486-linux-gnu/4.7/ -lgfortran fortranCode4.o cCode4.o -o hello4
#./hello4
Теперь продемонстрируем передачу символьных строк из Си в Фортран и обратно.

Файл cCode5.c:
#include<stdio.h>
void
     c_function_(char* string){
     printf("%s\n", string);
}
 Файл fortranCode5.f90:
program hello
    implicit none
    character*37 string
    string="Created in fortran, outputed from C!"
    string(37:37)=char(0)
    call c_function(string)
end program hello
#gfortran -O2 -g -o fortranCode5.o -c fortranCode5.f90
#gcc -O2 -g -o cCode5.o -c cCode5.c
#gcc -L /usr/lib/gcc/i486-linux-gnu/4.7/ -lgfortran fortranCode5.o cCode5.o -o hello5
#./hello5 
Теперь наоборот. Сформируем строку в Си, а напечатаем в Фортране.
Файл cCode6.c:
#include<string.h>
void
main(){
     char string[37];
     int length = sizeof(string);
     strncpy(string, "Created in C, outputed from Fortran!", length);
     fortran_function_(string, &length);
}
Файл fortranCode6.f90:
subroutine fortran_function(string, length)
    implicit none
    character*(*) string
    integer length
    write(*,100)string(1:length)
100 format(a)
    return
end subroutine fortran_function
#gfortran -O2 -g -o fortranCode6.o -c fortranCode6.f90
#gcc -O2 -g -o cCode6.o -c cCode6.c
#gcc -L /usr/lib/gcc/i486-linux-gnu/4.7/ -lgfortran fortranCode6.o cCode6.o -o hello6
#./hello6
Все примеры протестированы в Debian Wheezy.

четверг, 28 июня 2012 г.

Переменные окружения, влияющие на способ компиляции программ в GCC

C_INCLUDE_PATH - (для языка си) содержит список каталогов для поиска включаемых по директиве include заголовочных файлов, аналогична опции командной строки -isystem;
COMPILER_PATH - содержит список путей к каталогам, где компилятор проводит поиск своих подпрограмм, в случае ,если они не были найдены с помощью установки переменной GCC_EXEC_PREFIX;
CPATH - (для языков си, си++, объектный си) действует аналогично опции командной строки -I. Содержит список путей для поиска включаемых заголовочных файлов. Эти пути просматриваются после путей, указанных в -I;
CPLUS_INCLUDE_PATH - (для языка си++)содержит список каталогов для поиска включаемых по директиве include заголовочных файлов, аналогична опции командной строки -isystem. Эти каталоги просматриваются после каталогов, указанных в -isystem;
DEPENDENCIES_OUTPUT - препроцессор использует эту переменную для определения файла куда будут записываться правила зависимостей компоновки и цели, для которой создается отдельное правило. Аналогична сочетанию опций командной строки -MM, -MF, и -MT;
GCC_EXEC_PREFIX - используется для назначения префикса имен, вызываемых компилятором подпрограмм;
LANG - используется для указания компилятору набора кодировки, используемого для представления отдельных расширенных буквенных символов, текстовых строк и комментариев;
LC_ALL - замещает любые установки переменных LC_MESSAGES и LC_СTYPE;
LC_СTYPE - указывает способ кодировки расширенных буквенных знаков, имеющих мультибайтное представление;
LC_MESSAGES - указывает язык, используемый для выдачи компилятором диагностических сообщений;
LD_LIBRARY_PATH - применяется при выполнении программ. Предоставляет список путей, в которых программы во время своего запуска находят разделяемые библиотеки;
LD_RUN_PATH - применяется при выполнении программ. Предоставляет список путей, в которых программы во время своего запуска находят файл, содержащий имена символов и соответствующие им адреса. Аналогична опции -R утилиты ld;
LIBRARY_PATH - задает пути, где компоновщик ищет компоновочные сценарии и библиотеки, указанные опцией -l("эль"). Эти пути просматриваются после путей, заданных опцией -L;
OBJC_INCLUDE_PATH - (для объектного си) аналогична опции командной строки -isystem. Содержит список путей, где ищутся заголовочные include файлы. Эти каталоги просматриваются после каталогов, указанных в -isystem;
SUNPRO_OUTPUT - аналогична DEPENDENCIES_OUTPUT ?;
TMPDIR - содержит полный путь, где компилятор будет сохранять временные файлы;

пятница, 23 октября 2009 г.

Создание базы данных tags

Пусть мы создаем эту базу из исходников на языке си. Тогда:
#cd /my/working/directory
#find . -regex '.*\.c$\|.*\.h$' -print >taglist.tmp
#ctags -L taglist.tmp

В текущей директории и появиться нужный нам файл tags.
Теперь для поиска функции someFunction() делаем так:
#vi -t someFunction
Файл taglist.tmp можно вытереть.