Hi,
I am stuck at a point where I am using mixed language programming of C++ and FORTRAN. I have a C++ function in a dll which returns a pointer. I tried to call it from my FORTRAN program. I have no problem in compiling, linking and running. However, after the run I get the C pointer returned as 0. It is not a problem with the function in the dl because I have checked with the dll being called from both C++ and C# programs. So I think it is something to dow ith FORTRAN calling the C++ function. Here is the structure of the program:
Here is my FORTRAN code:
In the above set up the pointer returned by the c_p=CalcAirProperties() call is 0 and thus the values f_p is not pointing to the right array start.
So to remove all the problems with pointers I converted the C++ function to accept an array (by reference) so that I can set the desired array values inside the C++ function and thus pass the array back to FORTRAN. Here is what I did for that:
Here is my FORTRAN code:
The above method also did not work. So I am kind of lost. I am still a newbie when it comes to mixed language programming.
I am using gcc with Code::Blocks to create the C++ dll and gfortran with Simply Fortran IDE to create the fortran exe.
I would appreciate any help in this regards.
Regards
SNKP
I am stuck at a point where I am using mixed language programming of C++ and FORTRAN. I have a C++ function in a dll which returns a pointer. I tried to call it from my FORTRAN program. I have no problem in compiling, linking and running. However, after the run I get the C pointer returned as 0. It is not a problem with the function in the dl because I have checked with the dll being called from both C++ and C# programs. So I think it is something to dow ith FORTRAN calling the C++ function. Here is the structure of the program:
// C++ Header // --------------- # include statements #ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport) #else // #define DLL_EXPORT __declspec(dllimport) #endif //#ifdef __cplusplus extern "C" { double DLL_EXPORT __cdecl *CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure); } // --------------- //C++ source code // --------------- double DLL_EXPORT __cdecl *CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure) { double *AirProperties = new double[7]; //Do Calculations return AirProperties } // ---------------
Here is my FORTRAN code:
!******************** PROGRAM ProgramMain USE Statements USE iso_c_binding, ONLY : c_ptr,c_double,c_f_pointer IMPLICIT NONE TYPE(c_ptr) :: c_p REAL(c_double), POINTER :: f_p(:) INTERFACE FUNCTION CalcAirProperties(InputComb, InpValue1,InpValue2,BarometricPressure) BIND(C,NAME='CalcAirProperties') USE ISO_C_BINDING INTEGER(kind=C_INT), INTENT(IN) :: InputComb REAL(kind=C_DOUBLE), INTENT(IN) :: InpValue1 REAL(kind=C_DOUBLE), INTENT(IN) :: InpValue2 REAL(kind=C_DOUBLE), INTENT(IN) :: BarometricPressure TYPE(c_ptr) :: CalcAirProperties END FUNCTION END INTERFACE REAL :: TempDB_Test REAL :: TempRH_Test REAL :: BaroPressure TempDB_Test = 308.15 TempRH_Test = 0.69 BaroPressure = 101.325 c_p = CalcAirProperties(2,TempDB_Test,TempRH_Test,BaroPr essure) CALL c_f_pointer(c_p,f_p,[7]) RHiC = f_p(3) RhoAiC = f_p(7) END ProgramMain !********************
In the above set up the pointer returned by the c_p=CalcAirProperties() call is 0 and thus the values f_p is not pointing to the right array start.
So to remove all the problems with pointers I converted the C++ function to accept an array (by reference) so that I can set the desired array values inside the C++ function and thus pass the array back to FORTRAN. Here is what I did for that:
// C++ Header // --------------- # include statements #ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport) #else // #define DLL_EXPORT __declspec(dllimport) #endif //#ifdef __cplusplus extern "C" { void DLL_EXPORT __cdecl CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure,double PropertyArray[]); } // --------------- //C++ source code // --------------- void DLL_EXPORT __cdecl CalcAirProperties(int InputCombination, double Input1, double Input2, double Pressure,double PropertyArray[]) { double *AirProperties = new double[7]; //Do Calculations for(int i =0;i<7;i++) { PropertyArray(i) = AirProperties(i); } } // ---------------
Here is my FORTRAN code:
!******************** PROGRAM ProgramMain USE Statements USE iso_c_binding, ONLY : c_ptr,c_double,c_f_pointer IMPLICIT NONE TYPE(c_ptr) :: c_p REAL(c_double), POINTER :: f_p(:) INTERFACE SUBROUTINE CalcAirProperties(InputComb, InpValue1,InpValue2,BarometricPressure,PropertyArr ay) BIND(C,NAME='CalcAirProperties') USE ISO_C_BINDING INTEGER(kind=C_INT), INTENT(IN) :: InputComb REAL(kind=C_DOUBLE), INTENT(IN) :: InpValue1 REAL(kind=C_DOUBLE), INTENT(IN) :: InpValue2 REAL(kind=C_DOUBLE), INTENT(IN) :: BarometricPressure REAL(kind=C_DOUBLE), DIMENSION(7), INTENT(OUT) :: PropertyArray END SUBROUTINE END INTERFACE REAL :: TempDB_Test REAL :: TempRH_Test REAL :: BaroPressure REAL(kind=C_DOUBLE), DIMENSION(7) :: PropertyArray TempDB_Test = 308.15 TempRH_Test = 0.69 BaroPressure = 101.325 CALL CalcAirProperties(2,TempDB_Test,TempRH_Test,BaroPr essure,PropertyArray) RHiC = PropertyArray(3) RhoAiC = PropertyArray(7) END ProgramMain !********************
The above method also did not work. So I am kind of lost. I am still a newbie when it comes to mixed language programming.
I am using gcc with Code::Blocks to create the C++ dll and gfortran with Simply Fortran IDE to create the fortran exe.
I would appreciate any help in this regards.
Regards
SNKP