2011-12-26 2 views
3

У меня есть вопрос о программировании на смешанном языке (C/C++ и FORTRAN) с использованием gcc и gfortran. Я искал много «смешивания fortran с языком X» и не смог решить эту проблему.C/C++, FORTRAN, символы подчеркивания и GNU Autotools

Я не уверен, что это проблема связи или проблема с компилятором, или и то, и другое.

Я создал три файла, и я использую GNU Autotools для создания грубого приложения , но он должен иметь возможность самостоятельно создавать приложение из команды .

Файл: C (main.c) будет движущим приложением, что вызывает несколько FORTRAN функции:

/* this is a simple program */ 

#include <stdio.h> 

/* add the extern function definition */ 
#include "fooonly.h" 

// this is not working for the mixed language programming stuff yet... 

/* this is the main program section */ 
int main(int argc, char *argv[]) 
{ 
    int a = 36; 
    int b = 24; 
    int c = 0; 

    printf("hi mom\n"); 

    /* now call a FORTRAN function from C */ 
    c = NGCD(&a, &b); 
    printf("NGCD(%d,%d)=%d\n", a, b, c); 

    return 0; 

}

фортрановская функция, которая будет наиболее часто содержит FORTRAN 77 (но также может содержать код FORTRAN90/95), выглядит так:

c$$$  The following introductory example in FORTRAN 77 finds the 
c$$$  $  greatest common divisor for two numbers A and B using a 
c$$$  $  verbatim implementation of Euclid's algorithm. 

     FUNCTION NGCD(NA, NB) 
     IA = NA 
     IB = NB 
1 IF (IB.NE.0) THEN 
     ITEMP = IA 
     IA = IB 
     IB = MOD(ITEMP, IB) 
     GOTO 1 
     END IF 
     NGCD = IA 
     RETURN 
     END 

Использование Dev. Studio 6/Compaq Digital Fortran 6.0, это прекрасно работает. В самом деле, я не должен использовать #define IfDef __cplusplus/# ENDIF и может просто создать файл C, который выглядит как:

/* this is a simple program */ 

#include <stdio.h> 

/* add the extern function definition */ 
extern "C" int __stdcall NGCD(int *a, int *b); 

/* this is the main program section */ 
int main(int argc, char *argv[]) 
{ 
    int a = 36; 
    int b = 24; 
    int c = 0; 

    printf("hi mom\n"); 

    /* now call a FORTRAN function from C */ 
    c = NGCD(&a, &b); 
    printf("NGCD(%d,%d)=%d\n", a, b, c); 

    return 0; 
} 

и скомпилировать его с FORTRAN листинг выше, ссылки приложения , запускает и генерирует правильные результаты.

C:\fooonly>fooonly.exe 
hi mom 
NGCD(36,24)=12 

C:\fooonly> 

Когда я пытаюсь Наивысшая повторить этот процесс, используя GNU Autotools на MinGW или OSX, я по-прежнему получаю следующие ошибки:

macbook:makecheck $ make 
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"fooonly\" -DVERSION=\"1.0.2\" -I.  -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c 
mv -f .deps/main.Tpo .deps/main.Po 
gfortran -g -O2 -o fooonly main.o ngcd.o 
Undefined symbols for architecture x86_64: 
    "_NGCD", referenced from: 
     _main in main.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 
make: *** [fooonly] Error 1 
macbook:makecheck $ 

где Makefile (генерируется GNU Autotools), в основном содержит следующие команды:

macbook:makecheck $ gcc -c main.c 
macbook:makecheck $ gfortran -c ngcd.f 
macbook:makecheck $ gcc -o fooonly main.c ngcd.o 
Undefined symbols for architecture x86_64: 
    "_NGCD", referenced from: 
     _main in cc9uPBWl.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 
macbook:makecheck $ 

Мой configure.in сценарий не содержит ничего более:

AC_INIT(main.c) 
AM_INIT_AUTOMAKE(fooonly, 1.0.2) 

## C/C++ compiler section 
AC_PROG_CC 

## fortran section 
AC_PROG_F77 

## output section 
AC_OUTPUT(Makefile) 

, который, по существу,

macbook:makecheck $ gcc -c main.c 
macbook:makecheck $ gfortran -c ngcd.f 
macbook:makecheck $ gcc -o fooonly main.c ngcd.o 

правильно?

Я пытаюсь построить это на нескольких платформах (Linux, Win32/64, OSX, и т.д.) и хотите использовать GNU Autotools, и я знаю, что это сделано с других проектов с открытым исходным кодом, но configure.in для тех проектов - это намного больше, чем мои новички GNU Autotools, и я получаю , немного перегруженный, пытаясь их расшифровать.

Я предполагаю, что это имеет какое-то отношение:

1) Определения, которые я использовал в сценарии configure.in, 2) Я не включая некоторые волшебный набор переключателей (т.е. -fno-вторых, подчеркнуть?), или 3) Некоторая комбинация двух?

Я закрываю, и если да, то как мне получить приложение для сборки?

+0

"macbook: makecheck $ gcc -o fooonly main.c ngcd.o" не лучше ли вам переходить 'main.o', а не' main.c'? –

+0

Да, действительно. Это была опечатка. – user1116524

ответ

4

До тех пор, пока у вас есть компилятор, но за последние несколько лет я рекомендую использовать привязку ISO C для смешивания Fortran с другими языками. Затем вы можете пропустить имя mangling с подчеркиванием и аналогичными проблемами, связанными с компилятором и платформой. Если у вас есть устаревший код FORTRAN 77, который вы не хотите изменять, вы можете написать небольшую процедуру склейки Fortran 2003 между C и FORTRAN 77. Более старые инструкции описывают предыдущий метод, который требует большего понимания внутренних интерфейсов и был более компилятор/платформа зависит. Для нового метода ознакомьтесь с главой руководства gfortran «Программирование на смешанном языке» и предыдущими вопросами/ответами.

С помощью кода Fortran проще связать с gfortran, поскольку он включает библиотеки времени исполнения Fortran. Я думаю, что то же самое относится к C++, поэтому, если у вас есть оба, вам придется явно включать библиотеку времени выполнения того или другого.

P.S. Ниже приведен пример с использованием Fortran ISO C Переплет:

function NGCD (na, nb) bind (C, name="NGCD") 
    use iso_c_binding 
    implicit none 
    integer (c_int) :: ngcd 
    integer (c_int), intent (in) :: na, nb 
    integer (c_int) :: ia, ib, itemp 
    ia = na 
    ib = nb 

    do while (ib /= 0) 
     itemp = ia 
     ia = ib 
     ib = mod(itemp, ib) 
    end do 

    ngcd = ia 

    return 
end function NGCD 

Compile/связь с:

gcc -c main.c 
gfortran main.o ngcd.f90 
+0

Отличное решение, и в будущем я думаю, что я предлагаю это сотрудникам. К сожалению, я работаю с устаревшим кодом, который требует F77. – user1116524

+0

Иногда я не понимаю требования к сохранению устаревших программ F77. Я сам поддерживаю программу, которая только f95, но f77 просто слишком устарела. Возможности новых стандартов Fortran могут быть без проблем использованы в исходном коде фиксированного формата из старых программ. Трудно найти компилятор Fortran, который знает только F77 за пределами исторических платформ и мэйнфреймов. –

-1

Я никогда не получил достаточного ответа, поэтому я починил временное решение (игнорирует случай в Фортране код) и разместил его на моем блоге forufus. В будущем мне придется разрабатывать ключи компилятора.

Смежные вопросы