Как связать подпрограмму fortran с основной программой cpp?

Я пытаюсь скомпилировать программу на C ++, но она не работает.
Сначала я должен сказать, что c ++ — это не тот язык, который я действительно знаю, я использую Fortran. Во всяком случае, основная программа на С ++ вызывает подпрограмму на фортране. Я могу скомпилировать эту подпрограмму, но когда я хочу скомпилировать программу на С ++, возникает ошибка ссылки.
Реальная программа просто огромна и вызывает много подпрограмм, поэтому я провел простой тест (простая программа, вызывающая только одну подпрограмму), и она не работает так же хорошо! Когда я хочу создать .x, моя подпрограмма не определена.
Вот программа на С ++ (test-TQINIT.cpp) и подпрограмма (TQINIT.f).

тест-TQINIT.cpp:

  #include <iostream>

using namespace std;

extern "C"{
void  TQINIT_(int*, int*);
}

main()
{ int NWG;
NWG=80000;
int *IWSG = new int[NWG];
TQINIT_(IWSG,&NWG);
}

TQINIT.f:

  SUBROUTINE TQINIT(IWSG,NWG)
IMPLICIT NONE

INTEGER NWG
INTEGER IWSG(NWG)
LOGICAL TQG2ERR
INTEGER IERR

CALL TQRSERR

CALL TQINI(NWG,IWSG)

IF (TQG2ERR(IERR)) THEN
WRITE(6,*)'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
WRITE(6,*)'ERROR INITIALIZING (TQINIT) !!!'
WRITE(6,*)'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
STOP
ENDIF

END

Я компилирую подпрограмму, используя:

  gfortran -c TQINIT.f

и получите TQINIT.o

Затем я компилирую основную программу, используя:

  g++ -c test-TQINIT.cpp

и получите тест-TQINIT.o.

Затем для создания .x я использую (TQINIT.f нужна библиотека):

  g++ test-TQINIT.o TQINIT.o -L/usr/local/thermocalc/3.0/SDK/TQ8 -ltq-linux-x86_64-gfortran44-8 -o test-TQINIT.x

Вот что я получаю:

  test-TQINIT.o: In function `main':
test-TQINIT.cpp:(.text+0x33): undefined reference to `TQINIT_'
collect2: ld returned 1 exit status

Я надеюсь, что кто-то сможет мне помочь.
Спасибо заранее.

1

Решение

Fortran нечувствителен к регистру, и имя подпрограмм в объектном файле обычно (насколько я знаю) заканчивается строчными буквами с подчеркиванием, поэтому ваше имя, вероятно, называется tqinit_ и не TQINIT_поэтому ваш вызов в C ++ должен быть строчным.

Вы можете проверить имя в объектном файле с помощью objdump -t TQINIT.o команда, приведенная в ответе Александра Фогта, или более простая nm TQINIT.o что более кратко.

2

Другие решения

Если вы используете ISO_C_BINDING в Фортране, у вас будет контроль над точными именами подпрограмм, которые будут видны на другом языке, например, case, без подчеркивания. Вы также можете объявить аргументы, чтобы гарантировать соответствие C / C ++. Подробнее об этой теме смотрите https://stackoverflow.com/questions/tagged/fortran-iso-c-binding

1

Я не эксперт по смешиванию C и Fortran, но я всегда связывал код Fortran напрямую, используя

g++ test-TQINIT.cpp TQINIT.o -L/usr/local/thermocalc/3.0/SDK/TQ8 \
-ltq-linux-x86_64-gfortran44-8 -o test-TQINIT.x

вместо того, чтобы скомпилировать эти два файла по отдельности, а затем связать … Возможно, это поможет (хотя ваш путь должен работать, по крайней мере, с простым примером, который я пробовал).

КСТАТИ:
Вы можете узнать, как функции в вашем объекте Fortran вызываются с помощью команды

objdump -t TQINIT.o

Это должно дать вам правильное имя функции для вызова.

0

Как предложил Steabert, изменение прописных букв на строчные решило проблему с ссылками.
Спасибо всем за вашу помощь.

0
По вопросам рекламы [email protected]