Please help with linking vs7 c++ to fortran dll

G

Guest

Help! I'm new to c++, and am breaking my teeth on MS Visual C++ (bundled
within Visual Studio .NET 2003). Am trying to link simple c++ code to
fortran dlls created in Compaq Visual Fortran (v6.1). Posts concerning
this topic are common, but none of the posted solutions I've tried work
correctly with the above software. The linker can't seem to find the dll
(reports 'unresolved external symbol __imp__IMSL_FUN@8'; IMSL_FUN.dll is
the f77 library), although the library exists, compiled fine within CVF,
and its directory is declared in Visual C++'s Project|Properties
|Linker|Additional Library Directories. I'm hoping this is a simple
problem. The f77 and c++ source code is extremely simple and is included
below along with both the CVF and VS7 C++ compiler/linker messages,

! ------------------ begin f77
! imsl_fun.for
!
! FUNCTIONS/SUBROUTINES exported from IMSL_FUN.dll:
! IMSL_FUN - subroutine
!
double precision function IMSL_FUN(A,B)

! Expose subroutine IMSL_FUN to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::IMSL_FUN

implicit none
double precision A, B
IMSL_FUN = A / B
return
end

! ------------------ end f77

Compiling Fortran...
C:\home\rolf\local\lib\imsl_fun\IMSL_FUN.for
Linking...
Creating library Debug/imsl_fun.lib and object Debug/imsl_fun.exp

imsl_fun.dll - 0 error(s), 0 warning(s)



// ------------------ begin c++
// testIMSL.NET.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
extern "C" __declspec(dllimport) short __stdcall IMSL_FUN(double* a, double*
b);

int _tmain(int argc, _TCHAR* argv[])
{
double y = -1.e-12;
double a, b;
a = 1.;
b = 1.;
std::cout << "Before calling IMSL_FUN y = " << y << std::endl;
y = IMSL_FUN(&a, &b);
std::cout << "After calling IMSL_FUN y = " << y << std::endl;
return 0;
}
// ------------------ end c++

Compiling...
testIMSL.cpp
Linking...
testIMSL.obj : error LNK2019: unresolved external symbol __imp__IMSL_FUN@8
referenced in function _main
Debug/testIMSL.exe : fatal error LNK1120: 1 unresolved externals

testIMSL.NET - 2 error(s), 0 warning(s)


Any ideas?
 
C

Carl Daniel [VC++ MVP]

For starters let me say that I know nothing about modern Fortran (having not
done any since the early 80's).

It sounds like you're missing the import library for the Fortran DLL in your
C++ project. There's no need (or value) in having the DLL itself specified
in the C++ project at all. Rather, you should have gotten a .lib file that
specifies the exported symbols from the DLL. Make sure that .lib
(imsl_fun.lib) is included in the additional library dependencies. Note
that you need to mention the library explicitly, not just the directory
where it resides.

If you've already done that (it's not clear from your description below,
since you only explicitly mention the DLL itself), then your problem is one
of naming convention. To resolve that problem, you need to become best
friends with the dumpbin utility that's included with Visual Studio.

Run dumpbin /exports IMSL_FUN.DLL to see the names of the exported
functions. You'll probably have no problem identifying your function (as
there's a good chance it's the only exported name). Off hand, I'm to to
guess that it's probably named "IMSL_FUN", while the C++ compiler wants it
to be named IMSL_FUN@8. If the Fortran function is truly compiled for the
__stdcall calling convention, then you have to resolve the name conflict by
generating a new import library that renames the function. On the other
hand, it might be that the options specified to the Fortran compiler aren't
correct and the function isn't really __stdcall.

Without having Compaq Visual Fortran, that's about the most help I can
offer. If you learn more details using dumpbin and still aren't able to
resolve the problem, post again.

-cd

Help! I'm new to c++, and am breaking my teeth on MS Visual C++
(bundled within Visual Studio .NET 2003). Am trying to link simple
c++ code to fortran dlls created in Compaq Visual Fortran (v6.1).
Posts concerning
this topic are common, but none of the posted solutions I've tried
work correctly with the above software. The linker can't seem to find
the dll (reports 'unresolved external symbol __imp__IMSL_FUN@8';
IMSL_FUN.dll is the f77 library), although the library exists,
compiled fine within CVF, and its directory is declared in Visual
C++'s Project|Properties
Linker|Additional Library Directories. I'm hoping this is a simple
problem. The f77 and c++ source code is extremely simple and is
included below along with both the CVF and VS7 C++ compiler/linker
messages,

! ------------------ begin f77
! imsl_fun.for
!
! FUNCTIONS/SUBROUTINES exported from IMSL_FUN.dll:
! IMSL_FUN - subroutine
!
double precision function IMSL_FUN(A,B)

! Expose subroutine IMSL_FUN to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::IMSL_FUN

implicit none
double precision A, B
IMSL_FUN = A / B
return
end

! ------------------ end f77

Compiling Fortran...
C:\home\rolf\local\lib\imsl_fun\IMSL_FUN.for
Linking...
Creating library Debug/imsl_fun.lib and object Debug/imsl_fun.exp

imsl_fun.dll - 0 error(s), 0 warning(s)



// ------------------ begin c++
// testIMSL.NET.cpp : Defines the entry point for the console
application. //

#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
extern "C" __declspec(dllimport) short __stdcall IMSL_FUN(double* a,
double* b);

int _tmain(int argc, _TCHAR* argv[])
{
double y = -1.e-12;
double a, b;
a = 1.;
b = 1.;
std::cout << "Before calling IMSL_FUN y = " << y << std::endl;
y = IMSL_FUN(&a, &b);
std::cout << "After calling IMSL_FUN y = " << y << std::endl;
return 0;
}
// ------------------ end c++

Compiling...
testIMSL.cpp
Linking...
testIMSL.obj : error LNK2019: unresolved external symbol
__imp__IMSL_FUN@8 referenced in function _main
Debug/testIMSL.exe : fatal error LNK1120: 1 unresolved externals

testIMSL.NET - 2 error(s), 0 warning(s)


Any ideas?
 
G

Guest

Carl --
Thanks very much for your reply -- explicitly specifying the .lib file
dependency, and correcting for name decoration by making the following
changes to the f77 export declaration fixed it:

!DEC$ ATTRIBUTES DLLEXPORT :: IMSL_FUN
!DEC$ ATTRIBUTES ALIAS:'_IMSL_FUN@8' :: IMSL_FUN

Thanks again!
--Rolf

Carl Daniel said:
For starters let me say that I know nothing about modern Fortran (having not
done any since the early 80's).

It sounds like you're missing the import library for the Fortran DLL in your
C++ project. There's no need (or value) in having the DLL itself specified
in the C++ project at all. Rather, you should have gotten a .lib file that
specifies the exported symbols from the DLL. Make sure that .lib
(imsl_fun.lib) is included in the additional library dependencies. Note
that you need to mention the library explicitly, not just the directory
where it resides.

If you've already done that (it's not clear from your description below,
since you only explicitly mention the DLL itself), then your problem is one
of naming convention. To resolve that problem, you need to become best
friends with the dumpbin utility that's included with Visual Studio.

Run dumpbin /exports IMSL_FUN.DLL to see the names of the exported
functions. You'll probably have no problem identifying your function (as
there's a good chance it's the only exported name). Off hand, I'm to to
guess that it's probably named "IMSL_FUN", while the C++ compiler wants it
to be named IMSL_FUN@8. If the Fortran function is truly compiled for the
__stdcall calling convention, then you have to resolve the name conflict by
generating a new import library that renames the function. On the other
hand, it might be that the options specified to the Fortran compiler aren't
correct and the function isn't really __stdcall.

Without having Compaq Visual Fortran, that's about the most help I can
offer. If you learn more details using dumpbin and still aren't able to
resolve the problem, post again.

-cd

Help! I'm new to c++, and am breaking my teeth on MS Visual C++
(bundled within Visual Studio .NET 2003). Am trying to link simple
c++ code to fortran dlls created in Compaq Visual Fortran (v6.1).
Posts concerning
this topic are common, but none of the posted solutions I've tried
work correctly with the above software. The linker can't seem to find
the dll (reports 'unresolved external symbol __imp__IMSL_FUN@8';
IMSL_FUN.dll is the f77 library), although the library exists,
compiled fine within CVF, and its directory is declared in Visual
C++'s Project|Properties
Linker|Additional Library Directories. I'm hoping this is a simple
problem. The f77 and c++ source code is extremely simple and is
included below along with both the CVF and VS7 C++ compiler/linker
messages,

! ------------------ begin f77
! imsl_fun.for
!
! FUNCTIONS/SUBROUTINES exported from IMSL_FUN.dll:
! IMSL_FUN - subroutine
!
double precision function IMSL_FUN(A,B)

! Expose subroutine IMSL_FUN to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::IMSL_FUN

implicit none
double precision A, B
IMSL_FUN = A / B
return
end

! ------------------ end f77

Compiling Fortran...
C:\home\rolf\local\lib\imsl_fun\IMSL_FUN.for
Linking...
Creating library Debug/imsl_fun.lib and object Debug/imsl_fun.exp

imsl_fun.dll - 0 error(s), 0 warning(s)



// ------------------ begin c++
// testIMSL.NET.cpp : Defines the entry point for the console
application. //

#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
extern "C" __declspec(dllimport) short __stdcall IMSL_FUN(double* a,
double* b);

int _tmain(int argc, _TCHAR* argv[])
{
double y = -1.e-12;
double a, b;
a = 1.;
b = 1.;
std::cout << "Before calling IMSL_FUN y = " << y << std::endl;
y = IMSL_FUN(&a, &b);
std::cout << "After calling IMSL_FUN y = " << y << std::endl;
return 0;
}
// ------------------ end c++

Compiling...
testIMSL.cpp
Linking...
testIMSL.obj : error LNK2019: unresolved external symbol
__imp__IMSL_FUN@8 referenced in function _main
Debug/testIMSL.exe : fatal error LNK1120: 1 unresolved externals

testIMSL.NET - 2 error(s), 0 warning(s)


Any ideas?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top