Monday, October 02, 2006
CPP calling FORTRAN DLL
Newbie guide.
Using Microsoft Visual Studio MSVS 2005 C++ CPP code to call a dll made by Intel Visual FORTRAN.
Create your Fortran DLL
1. New Project -> Intel(R) Fortran Projects -> Dynamic-link Library.
Name: FDLL
OK
FINISH
2. Edit FDLL.F90
! FDLL.f90
! Fortran subroutine which is called from a C main program.
! The source is structured so that it can be built either
! as a DLL or just mixed in with the C source directly.
!
SUBROUTINE FSUB (INT_ARG, STR_IN, STR_OUT)
IMPLICIT NONE
! If we're building a DLL, specify that DLL_ROUT is
! exported to a DLL. Key this off of the preprocessor
! symbol _DLL which is automatically defined if we're
! building a DLL.
!DEC$ IF DEFINED (_DLL)
!DEC$ ATTRIBUTES DLLEXPORT :: FSUB
!DEC$ END IF
INTEGER, INTENT(IN) :: INT_ARG
CHARACTER(*), INTENT(IN) :: STR_IN
CHARACTER(*), INTENT(OUT) :: STR_OUT
! This routine converts INT_ARG to a decimal string.
! appends the string value to STR_IN and stores it
! in STR_OUT. A trailing NUL is added to keep C
! happy.
!
! Note that there are implicit length arguments at the
! end of the argument list - see the CMAIN
! source for more details.
CHARACTER*5 INT_STR
WRITE (INT_STR,'(I5.5)')INT_ARG
STR_OUT = STR_IN // INT_STR // CHAR(0)
RETURN
END
3. Build
Create your CPP application
1. New Project -> Visual C++ -> Win32 Console Application
Name: USEDLL
OK
FINISH
2. Create FDLL.h (Right Click on Source Files -> Add -> New Item.. ->Header File(.h),Add
// FDLL.h : main header file for the FDLL DLL
#pragma once
/*
* The following ifdef block is the standard
* way of creating macros which make exporting
* from a DLL simpler. All files within this DLL
* are compiled with the FDLLSPEC symbol defined
* on the command line. This symbol should not be
* defined on any project that uses this DLL.
* This way any other project whose source files
* include this file see FDLLSPEC functions as being
* imported from a DLL, whereas this DLL
* sees symbols defined with this macro as being exported.
*/
#ifdef USEDLL
#define FDLLSPEC __declspec(dllimport)
#pragma message("automatic link to FDLL.lib")
#pragma comment(lib, "FDLL.lib")
#else
#define FDLLSPEC __declspec(dllexport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* In the following declaration of FSUB, note that there
are two additional arguments defined. By default,
Fortran code expects CHARACTER arguments to be passed
using two argument positions, an address and an integer
length (passed by value). When calling from
non-Fortran code, we need to explicitly pass the
length arguments unless other arrangements have been
made for the Fortran code not to expect them (C routine
attribute and REFERENCE argument attribute.) Intel
Fortran, by default, places these lengths at the end of
the argument list.
The routine name must be in uppercase unless the Fortran code
includes an appropriate ALIAS attribute.
*/
FDLLSPEC void FSUB (int *INT_ARG,
char *STR_IN,
char *STR_OUT,
size_t STR_IN_LEN,
size_t STR_OUT_LEN);
#ifdef __cplusplus
} /* extern "C" */
#endif
3. Edit USEDLL.cpp
// USEDLL.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
/* Main program written in C++ that calls a Fortran routine */
#include
#include
#include "FDLL.h"
int _tmain(int argc, _TCHAR* argv[])
{
char instring[40];
char outstring[40];
int intarg;
strcpy(instring,"Testing...");
intarg = 123;
/* Call Fortran routine - pass intarg by reference,
pass length of outstring explicitly */
FSUB(&intarg,instring,outstring,strlen(instring),sizeof(outstring));
printf("%s\n",outstring);
return 0;
}
4. Build, notice LNK2019 error
5. Fix error, tell preprocessor that it needs to look for DLL's and put *.lib so linker can find definitions.
Project -> USEDLL Properties -> Conifg Props -> C/C++ -> Preprocessor
Preprocessor Definitions = WIN32;_DEBUG;_CONSOLE;USEDLL
OK
Copy FDLL\FDLL\Debug\FDLL.lib to USEDLL\USEDLL Build
6. Open command prompt at USEDLL\debug7. Run program >USEDLL.exe, notice error.
8. Fix error, put DLL where it can be found by executable.
Copy FDLL\FDLL\Debug\FDLL.dll to USEDLL\debug9. Run program >USEDLL.exe
Ta-Da! Hope it saved you some time, because i sure wasted alot of it figuring this out.
Thanks to: Hans Dietrich
And the Intel Forums People.
Using Microsoft Visual Studio MSVS 2005 C++ CPP code to call a dll made by Intel Visual FORTRAN.
Create your Fortran DLL
1. New Project -> Intel(R) Fortran Projects -> Dynamic-link Library.
Name: FDLL
OK
FINISH
2. Edit FDLL.F90
! FDLL.f90
! Fortran subroutine which is called from a C main program.
! The source is structured so that it can be built either
! as a DLL or just mixed in with the C source directly.
!
SUBROUTINE FSUB (INT_ARG, STR_IN, STR_OUT)
IMPLICIT NONE
! If we're building a DLL, specify that DLL_ROUT is
! exported to a DLL. Key this off of the preprocessor
! symbol _DLL which is automatically defined if we're
! building a DLL.
!DEC$ IF DEFINED (_DLL)
!DEC$ ATTRIBUTES DLLEXPORT :: FSUB
!DEC$ END IF
INTEGER, INTENT(IN) :: INT_ARG
CHARACTER(*), INTENT(IN) :: STR_IN
CHARACTER(*), INTENT(OUT) :: STR_OUT
! This routine converts INT_ARG to a decimal string.
! appends the string value to STR_IN and stores it
! in STR_OUT. A trailing NUL is added to keep C
! happy.
!
! Note that there are implicit length arguments at the
! end of the argument list - see the CMAIN
! source for more details.
CHARACTER*5 INT_STR
WRITE (INT_STR,'(I5.5)')INT_ARG
STR_OUT = STR_IN // INT_STR // CHAR(0)
RETURN
END
3. Build
Create your CPP application
1. New Project -> Visual C++ -> Win32 Console Application
Name: USEDLL
OK
FINISH
2. Create FDLL.h (Right Click on Source Files -> Add -> New Item.. ->Header File(.h),Add
// FDLL.h : main header file for the FDLL DLL
#pragma once
/*
* The following ifdef block is the standard
* way of creating macros which make exporting
* from a DLL simpler. All files within this DLL
* are compiled with the FDLLSPEC symbol defined
* on the command line. This symbol should not be
* defined on any project that uses this DLL.
* This way any other project whose source files
* include this file see FDLLSPEC functions as being
* imported from a DLL, whereas this DLL
* sees symbols defined with this macro as being exported.
*/
#ifdef USEDLL
#define FDLLSPEC __declspec(dllimport)
#pragma message("automatic link to FDLL.lib")
#pragma comment(lib, "FDLL.lib")
#else
#define FDLLSPEC __declspec(dllexport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* In the following declaration of FSUB, note that there
are two additional arguments defined. By default,
Fortran code expects CHARACTER arguments to be passed
using two argument positions, an address and an integer
length (passed by value). When calling from
non-Fortran code, we need to explicitly pass the
length arguments unless other arrangements have been
made for the Fortran code not to expect them (C routine
attribute and REFERENCE argument attribute.) Intel
Fortran, by default, places these lengths at the end of
the argument list.
The routine name must be in uppercase unless the Fortran code
includes an appropriate ALIAS attribute.
*/
FDLLSPEC void FSUB (int *INT_ARG,
char *STR_IN,
char *STR_OUT,
size_t STR_IN_LEN,
size_t STR_OUT_LEN);
#ifdef __cplusplus
} /* extern "C" */
#endif
3. Edit USEDLL.cpp
// USEDLL.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
/* Main program written in C++ that calls a Fortran routine */
#include
#include
#include "FDLL.h"
int _tmain(int argc, _TCHAR* argv[])
{
char instring[40];
char outstring[40];
int intarg;
strcpy(instring,"Testing...");
intarg = 123;
/* Call Fortran routine - pass intarg by reference,
pass length of outstring explicitly */
FSUB(&intarg,instring,outstring,strlen(instring),sizeof(outstring));
printf("%s\n",outstring);
return 0;
}
4. Build, notice LNK2019 error
5. Fix error, tell preprocessor that it needs to look for DLL's and put *.lib so linker can find definitions.
Project -> USEDLL Properties -> Conifg Props -> C/C++ -> Preprocessor
Preprocessor Definitions = WIN32;_DEBUG;_CONSOLE;USEDLL
OK
Copy FDLL\FDLL\Debug\FDLL.lib to USEDLL\USEDLL Build
6. Open command prompt at USEDLL\debug7. Run program >USEDLL.exe, notice error.
8. Fix error, put DLL where it can be found by executable.
Copy FDLL\FDLL\Debug\FDLL.dll to USEDLL\debug9. Run program >USEDLL.exe
Ta-Da! Hope it saved you some time, because i sure wasted alot of it figuring this out.
Thanks to: Hans Dietrich
And the Intel Forums People.
Friday, April 07, 2006
TortoiseCVS
Bye Bye WinCVS, full functionality, no bugs and Windows Explorer integration... Hello TortoiseCVS.
What a relief to finally have an alternative to WinCVS.
What a relief to finally have an alternative to WinCVS.
Friday, March 31, 2006
Hewlett-Packard Test Drive
HP is letting people use their test servers that have a variety of OS's and Processors. Might be handy some day.
Monday, November 21, 2005
How To Write Unmaintainable Code
Probably the most complete collection of ways to write obfuscated code. Absolutely brilliant, i reference it every day when i'm coding to make sure my code stays Unique!

