Need help linking against static FORTRAN library
-
Hello All
I have a shared libraries (*.lib), pre-compiled using Intel Visual FORTRAN. I routinely link it into C++ programs using Microsoft Visual Studio (2013). The version of Qt I have is the one for the MSVS libraries.
Now I want to link it to a Qt app using Qt Creator. The library name is IVF_IO.lib. The function I need to access is getl(). (I am ignoring function arguments for now)
In my *.pro file I have:
- PRE_TARGETDEPS += C:/Users/.../libsd/IVF_IO.lib
- LIBS += -L"C:/Users/.../libsd/" -lIVF_IO
- INCLUDEPATH += C:/Users/.../libsd/include
In C:/Users/.../libsd/include, I have IVF_IO.h, which contains:
extern "C"
{
extern void getl();
}in the *.cpp file, I include:
#include <IVF_IO.h>and make the call:
getl();After I run qmake, the result of the build step is an "unresolved external symbol getl" error. FYI, I have tried adding the underscore ( getl_() ) to no avail. Any assistance that coudl be provided would be greatly appreciated. Thanks to all!
-
@towtruck
Hi,Remove the second
extern
in the header and use the underscore, FORTRAN adds those transparently:extern "C" { void getl_(); }
or equivalently:
extern "C" void getl_();
If you continue to have unresolved symbols, list them from the
lib
with windows' dependency walker program and make sure they're present in the static library.
PS.
When I need to deal with fortran I usually use a set of macros to wrap all of its antiquated nonsense, e.g.:#define FORT_SUBROUTINE(name) extern "C" void name##_ #define fchar(name) char * name #define fstring(name) char * name, int name##_len #define fint32(name) qint32 * name #define fint8(name) qint8 * name #define freal(name) float * name #define fdouble(name) double * name
then declarations turn into:
FORT_SUBROUTINE(ho_begin)(); FORT_SUBROUTINE(ho_set_ranges)(fdouble(rangesArray), fint8(size)); FORT_SUBROUTINE(ho_deformation_indirect)(fdouble(beta), fdouble(q));
and implementations (if you're providing from C to fortran) look like:
FORT_SUBROUTINE(ho_begin)() { // ... } FORT_SUBROUTINE(ho_set_ranges)(fdouble(rangesArray), fint8(size)) { // ... } FORT_SUBROUTINE(ho_deformation_indirect)(fdouble(beta), fdouble(q)) { // ... }
It's very ugly, but works okay.
Kind regards.
-
A belated thanks! to kshegunov for your reply.
I tried your initial suggestion, but no luck. Unfortunately here at my company I don't have access to Dependency Walker, so that gets ruled out.
I'm starting to believe that my problem is not related to FORTRAN. I recently created a C++ library (two versions actually, one created in VS & 1 in Qt Creator), and I had so much trouble getting Qt Creator creator to see it that I finally just made the 'library code' part of the Qt project. So basically I can't get the Qt build process to recognize any library. I'll try again, & once I solve that problem, I should be able to manage the FORTRAN library.
Thanks again. I'll keep y'all posted.
-
Hi,
Silly question but since you have Visual Studio 2013, did you install Qt for MSVC2013 ? If not that would explain the problem you are experiencing. Microsoft's compilers are not compatible one with the other so you can't mix and match libraries built with different versions of them.
-
Thank You!
Not a silly question.
Actually, I upgraded my version of VS from 2012 to 2013 to go with Qt for MSVC2013. Otherwise, I wouldn't even be able to compile pure C++ with Qt, which I have had no problem doing. I just can't seem to create even a pure C++ library in VS OR Qt, and have Qt recognize it. That will be my challenge in the next days, and is understandably slightly off-topic for this thread. But I will definitely report back.
Thanks to all!