linking G95 object .o in a QT4.5 project

30 views
Skip to first unread message

Denis

unread,
Oct 17, 2009, 2:16:00 PM10/17/09
to gg95
Hello ,

I would like to link a G95 FORtran compiled object into a C++ (QT4.5)
program.

A) I have made a small routine named subroutine GET_DATE()

subroutine GET_DATE(NAN,NMOIS,NJOUR)
integer*2 NAN
integer*2 NMOIS
integer*8 NJOUR
integer*2 values(8)

call date_and_time(VALUES=values)

NAN = VALUES(1)
NMOIS = VALUES(2)
NJOUR = VALUES(3)

return
end

compile with :

g95 -ftrace=full -c GET_DATE.FOR -o for_GET_DATE.o

this is done and make a for_GET_DATE.o
I have test it inside a FORtran program and it works.





B) now inside my small test QT program, I add for linking inside the
makefile.Debug the lines :

OBJECTS = debug/main.o \
debug/mainwindow.o \
debug/moc_mainwindow.o \
objetsFOR/for_GET_DATE.o


of course the linker use this OBJECTS
$(DESTDIR_TARGET): ui_mainwindow.h $(OBJECTS)
$(LINK) $(LFLAGS) -o $(DESTDIR_TARGET) $(OBJECTS) $(LIBS)



The C++ code is something like :
#include "mainwindow.h"
#include "ui_mainwindow.h"

//void g95_runtime_start(int argc, char *argv[]);
//void g95_runtime_stop(void);

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);

// g95_runtime_start(0,NULL);

// g95_runtime_stop();
}

MainWindow::~MainWindow()
{
delete ui;
}


For now I don't call the FORtran routine and just want to link the .o
Have to search how calling GET_DATE(...) after ;-)





C) but it seem that something is missing :
I have a lot of errors asking me

Running build steps for project QTcouplageFortran...
Configuration unchanged, skipping QMake step.
Starting: C:/Qt/2009.03/mingw/bin/mingw32-make.exe -w
mingw32-make: Entering directory `H:/DeveloppementQT/
QTcouplageFortran'
C:/Qt/2009.03/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory `H:/DeveloppementQT/
QTcouplageFortran'
g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-
pseudo-reloc -mthreads -Wl -Wl,-subsystem,windows -o debug
\QTcouplageFortran.exe debug/main.o debug/mainwindow.o debug/
moc_mainwindow.o objetsFOR/for_GET_DATE.o -L"c:\Qt\2009.03\qt\lib" -
lmingw32 -lqtmaind -lQtGuid4 -lQtCored4
mingw32-make[1]: Leaving directory `H:/DeveloppementQT/
QTcouplageFortran'
mingw32-make: Leaving directory `H:/DeveloppementQT/QTcouplageFortran'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xe): undefined reference
to `_g95_filename'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x16): undefined
reference to `_g95_line'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x1e): undefined
reference to `_g95_base'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x29): undefined
reference to `_g95_base'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x2f): undefined
reference to `_g95_filename'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x39): undefined
reference to `_g95_line'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x43): undefined
reference to `_g95_filename'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x4d): undefined
reference to `_g95_line'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xa2): undefined
reference to `_g95_date_and_time'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xab): undefined
reference to `_g95_filename'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xb5): undefined
reference to `_g95_line'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xc8): undefined
reference to `_g95_filename'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xd2): undefined
reference to `_g95_line'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xe6): undefined
reference to `_g95_filename'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0xf0): undefined
reference to `_g95_line'
objetsFOR/for_GET_DATE.o:GET_DATE.FOR:(.text+0x10b): undefined
reference to `_g95_base'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [debug\QTcouplageFortran.exe] Error 1
mingw32-make: *** [debug] Error 2
Exited with code 2.
Error while building project QTcouplageFortran
When executing build step 'Make'


I have seen about g95_runtime_start(0,NULL) but haven't found any
refs. about it.



Do you have any ideas of the case ?
Could you help ?

Bye
Denis

SimonG

unread,
Oct 19, 2009, 7:09:12 AM10/19/09
to gg95
Denis,

You shold start by reading the documentation http://ftp.g95.org/G95Manual.pdf
since it covers, in part at least, the issues you describe. It does
not tell you everything though.

The following is a simple example of a c++ main calling a subroutine
defined in a module:

C++ bit: (t.cxx)
#include <iostream>
using namespace std;
extern "C" {
void g95_runtime_start(int, char**);
void g95_runtime_stop();
void now();
}

int main(int argc, char** argv) {
g95_runtime_start(0, NULL);
cout << "Calling date_and_time ..." << endl;
now();
g95_runtime_stop();
}

Fortran bit: (date.f90)
module datetime
contains
subroutine now bind(c)
implicit none
character(len=8) :: today
call date_and_time(date=today)
write(*,'(a)') 'Today is '//today(7:8)//'/'//today(5:6)//'/'//today
(1:4)
end subroutine now
end module datetime

Building bit:
g95 -c date.f90
g++ -o t t.cxx date.o /usr/local/g95-install/lib/gcc-lib/i686-unknown-
linux-gnu/4.0.3/libf95.a


Note that you have to tell the linker where to find the g95 library
(libf95.a). Hope that helps,

Simon

Denis

unread,
Oct 20, 2009, 1:58:22 PM10/20/09
to gg95
Hello Simon,
Thanks for your reply.
Ok, I understood my mistake. I have then recoded and link.

i have in my .for file :

subroutine GET_DATE(NAN,NMOIS,NJOUR) bind(c)
...
end


and in C++ file

extern "C" {
void g95_runtime_start(int argc, char *argv[]);
void g95_runtime_stop(void);
void get_date(int *NAN,int *NMOIS,int *NJOUR);
}

main()
{
int nan;
int nmois;
int njour;

char toto[80];

g95_runtime_start(0,NULL);

get_date(&nan,&nmois,&njour);
sprintf(toto,"nan %d nmois %d njour %d",nan,nmois,njour);

g95_runtime_stop();
}

for now it doesn't work to pass the subroutine args but I have to
check on the web this.
I come back as soon I have the solution.

thanks for all.
denis

SimonG

unread,
Oct 21, 2009, 8:07:24 AM10/21/09
to gg95
I think you should call g95_runtime_stop() last and not before you've
made your call to get_date. I've updated my example to do more closely
what you want; I've only tested it on linux.

// C++ main
#include <iostream>
using namespace std;
extern "C" {
void g95_runtime_start(int, char**);
void g95_runtime_stop();
void now(int*, int*, int*);
}

int main(int argc, char** argv) {
g95_runtime_start(0, NULL);
cout << "Calling date_and_time ..." << endl;
int year, month, day;
now(&year, &month, &day);
cout << "anne = " << year << " ; mois = " << month << " ; jour = "
<< day << endl;
g95_runtime_stop();
}


// Fortran bit:
module datetime
contains
subroutine now(nan, nmois, njour) bind(c)
use iso_c_binding
implicit none
integer(c_int), intent(out) :: nan
integer(c_int), intent(out) :: nmois
integer(c_int), intent(out) :: njour
character(len=8) :: today
integer :: vals(8)
call date_and_time(date=today,values=vals)
write(*,'(a)') 'Today is '//today(7:8)//'/'//today(5:6)//'/'//today
(1:4)
nan = vals(1)
nmois = vals(2)
njour = vals(3)
end subroutine now
end module datetime


Denis

unread,
Oct 23, 2009, 10:59:43 AM10/23/09
to gg95
Hello Simon

it works ! magic

in fact, issue was from kind of integer.
Ok I understood something today, the use of C_INT
pass as kind of integer.

integer(c_int) nan
integer(c_int), intent(out) :: nmois
integer(c_int), intent(out) :: njour

thanks for all.
best
Reply all
Reply to author
Forward
0 new messages