- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all,
I am calling a Fortran subroutine from a C++ program. I am using Microsoft Visual Studio .NET 2003 with C++ ant Intel Fortran Compiler Integration for Microsoft Visual Studio .NET 2003, 10.1 2003.
I have set up the the Intel Fortran Compier as perhttp://software.intel.com/en-us/articles/configuring-visual-studio-for-mixed-language-applications/
The call from the C++ includes:
...
extern "C" {
void CARRAY(double *aa, double *ab,
double *integrtime, const int *nocstrs, const int *nocomp,
double *flin, double *tlin, double *plout, double xlin[],
double *flout, double *tlout, double *plin, double d[] );
....
CARRAY(&iin, &oout,
&deltat, &nocstrs, &nocomp,
&stFin, &stTin, &stPout, stXin,
&stFout, &stTout, &stPin, stXout) ;
And the Fortran code looks like the following:
subroutine CARRAY(N, M, INTGT, NZ, NCOMP, FIN, TIN, POUT, XIN, FOUT, TOUT, PIN, XOUT)
! Expose subroutine CALCE to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::CARRAY
integer :: NZ, NCOMP
double precision :: M, N, INTGT, FIN, TIN, POUT, FOUT, TOUT, PIN, XIN(3), XOUT(3)
INTEGER I
M = N + 3 ;
DO I = 1, 3
XOUT(I) = XIN(I) + 0.3
END DO
! Xout(1) = Xin(1) + 0.3 ;
! Xout(2) = Xin(2) + 0.5 ;
! Xout(3) = Xin(3) + 0.2 ;
PIN = POUT * 3.12 ;
TOUT = TIN * 1.35 ;
FOUT = FIN ;
return
end
I compile the Fortran routine as a library .lib, which I include in the compilation of the C++ code to create a dll to be used by a different software.
The problem:
If in the Fortran code I use the explicit expression:
Xout(1) = Xin(1) + 0.3 ;
Xout(2) = Xin(2) + 0.5 ;
Xout(3) = Xin(3) + 0.2 ;
I compile it as .lib, I include it in the C++ and compile it to a dll, this works correctly and my final software is able to use the dll correctly.
However, if I using a DO structure instead of the explicit expression above:
LOOP_1: DO I = 1, 3
XOUT(I) = XIN(I) + 0.3
END DO LOOP_1
or any other DO structure, the Fortran code compiles correctly without errors to a .lib, but the C++ code compilation gives errors:
LINK : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
LIBCD.lib(dbgheap.obj) : error LNK2005: _malloc already defined in MSVCRT.lib(MSVCR71.dll)
LIBCD.lib(dbgheap.obj) : error LNK2005: _free already defined in MSVCRT.lib(MSVCR71.dll)
LIBCD.lib(winxfltr.obj) : error LNK2005: ___CppXcptFilter already defined in MSVCRT.lib(MSVCR71.dll)
LIBCD.lib(crt0init.obj) : error LNK2005: ___xc_z already defined in MSVCRT.lib(cinitexe.obj)
LIBCD.lib(crt0init.obj) : error LNK2005: ___xc_a already defined in MSVCRT.lib(cinitexe.obj)
LIBCD.lib(crt0init.obj) : error LNK2005: ___xi_z already defined in MSVCRT.lib(cinitexe.obj)
LIBCD.lib(crt0init.obj) : error LNK2005: ___xi_a already defined in MSVCRT.lib(cinitexe.obj)
LIBCD.lib(dbgheap.obj) : warning LNK4006: _malloc already defined in MSVCRT.lib(MSVCR71.dll); second definition ignored
LIBCD.lib(dbgheap.obj) : warning LNK4006: _free already defined in MSVCRT.lib(MSVCR71.dll); second definition ignored
LIBCD.lib(winxfltr.obj) : warning LNK4006: ___CppXcptFilter already defined in MSVCRT.lib(MSVCR71.dll); second definition ignored
LIBCD.lib(crt0init.obj) : warning LNK4006: ___xc_z already defined in MSVCRT.lib(cinitexe.obj); second definition ignored
LIBCD.lib(crt0init.obj) : warning LNK4006: ___xc_a already defined in MSVCRT.lib(cinitexe.obj); second definition ignored
LIBCD.lib(crt0init.obj) : warning LNK4006: ___xi_z already defined in MSVCRT.lib(cinitexe.obj); second definition ignored
LIBCD.lib(crt0init.obj) : warning LNK4006: ___xi_a already defined in MSVCRT.lib(cinitexe.obj); second definition ignored
Creating library .\\Debug/ExampleUAM.lib and object .\\Debug/ExampleUAM.exp
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib 'LIBCD' conflicts with use of other libs; use /NODEFAULTLIB:library
libifcore.lib(for_main.obj) : error LNK2019: unresolved external symbol _MAIN__ referenced in function _main
.\\Debug/ExampleUAM.dll : fatal error LNK1120: 1 unresolved externals
Both expressions are equivalent but the DO seems not to be allowed. I have not checked yet with other basic expressions.
Could any body help, please? Am I missing the declaration of any libraries in the Fortran code?
Thank you very much in advance for your help.
Jesusp68
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The main problem is that your C++ and Fortran projects have different settings for which set of run-time libraries to use. Microsoft C++ defaults to DLL libraries and Intel Fortran defaults to static libraries. It also sort of looks as if you are combining a debug Fortran configuration with a release C++ configuration.
You can change the Fortran project to use the DLL libraries by the project property Fortran > Libraries > Use Runtime Library > Multithread DLL (/MD). This should eliminate most of the issues.
The second problem is that your Fortran project was created as a console application and not as a static library project type. Recreate the project, specifying a static library project type.
You can change the Fortran project to use the DLL libraries by the project property Fortran > Libraries > Use Runtime Library > Multithread DLL (/MD). This should eliminate most of the issues.
The second problem is that your Fortran project was created as a console application and not as a static library project type. Recreate the project, specifying a static library project type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, thanks for your answer. I am a bit puzzled. In fact the Fortran subroutine work correctly if I do not use the DO structure. If I just use the explicit calculation it works ok. I assume that if the settings on the dynamic libraries were not correct, the subroutine would not work irrespectively of the subroutine contents.
In the example below I have left the explicit calculation (in bold) added also an IF (also in bold):
subroutine CARRAY(N, M, INTGT, NZ, NCOMP, FIN, TIN, POUT, XIN, FOUT, TOUT, PIN, XOUT, BAS)
!
!DEC$ ATTRIBUTES DLLEXPORT::CARRAY
integer :: NZ, NCOMP
double precision :: M, N, INTGT, FIN, TIN, POUT, FOUT, TOUT, PIN, XIN(3), XOUT(3), BAS(13)
INTEGER I
M = N + 3 ;
IF (XIN(1) .GE. 0.8) THEN
Xout(1) = Xin(1)
ELSE
Xout(1) = Xin(1) + (BAS(13) + BAS(12))/100 ;
END IF
! DO 20 I = 2,3 ! Nonblock DO
! Xout(I) = Xin(I) + 0.5 ;
! 20 CONTINUE
Xout(2) = Xin(2) + 0.5 ;
Xout(3) = Xin(3) + 0.2 ;
PIN = POUT * 3.12 ;
TOUT = TIN * 1.35 ;
FOUT = FIN ;
return
This compiles well with the C++ code, see the message below:
------ Rebuild All started: Project: JesusP, Configuration: Debug Win32 ------
Deleting intermediate files and output files for project 'JesusP', configuration 'Debug|Win32'.
Compiling...
ExampleUAM.cpp
ExampleModel.cpp
c:\SIMSCI\DSS45\DSS45\ExampleUAM\ExampleModel.cpp(840) : warning C4101: 'MolarHoldupInput' : unreferenced local variable
Compiling resources...
Linking...
LINK : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
Creating library .\Debug/ExampleUAM.lib and object .\Debug/ExampleUAM.exp
LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
Build log was saved at "file://c:\Simsci\Dss45\Dss45\ExampleUAM\Debug\BuildLog.htm"
JesusP - 0 error(s), 3 warning(s)
---------------------- Done ----------------------
Rebuild All: 1 succeeded, 0 failed, 0 skipped
The C++ code runs correctly now and call the Fortran routine correctly, doing the required claculations correctly.
What do you think?
Thank you very much for your help
Regards
Jesus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you use the DO loop, because you are building a Debug confuiguration the compiler adds bounds-checking code, and this involves a call to the Fortran run-time library. This, in turn, links in the C run-time library and because your C and Fortran projects are using different sets of libraries, you get the errors. When you don't use the DO loop, no bounds checking code is needed because the compiler can see the array indexes directly.
I would strongly suggest that you set the runtime library type to be the same in the two projects. In C it is under Code Generation.
I would strongly suggest that you set the runtime library type to be the same in the two projects. In C it is under Code Generation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, it works now smootly. Thank you very much for your quick and accurate support. Regards. Jesus

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page