Я пытаюсь скомпилировать программу на 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
Я надеюсь, что кто-то сможет мне помочь.
Спасибо заранее.
Fortran нечувствителен к регистру, и имя подпрограмм в объектном файле обычно (насколько я знаю) заканчивается строчными буквами с подчеркиванием, поэтому ваше имя, вероятно, называется tqinit_
и не TQINIT_
поэтому ваш вызов в C ++ должен быть строчным.
Вы можете проверить имя в объектном файле с помощью objdump -t TQINIT.o
команда, приведенная в ответе Александра Фогта, или более простая nm TQINIT.o
что более кратко.
Если вы используете ISO_C_BINDING в Фортране, у вас будет контроль над точными именами подпрограмм, которые будут видны на другом языке, например, case, без подчеркивания. Вы также можете объявить аргументы, чтобы гарантировать соответствие C / C ++. Подробнее об этой теме смотрите https://stackoverflow.com/questions/tagged/fortran-iso-c-binding
Я не эксперт по смешиванию 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
Это должно дать вам правильное имя функции для вызова.
Как предложил Steabert, изменение прописных букв на строчные решило проблему с ссылками.
Спасибо всем за вашу помощь.