First a disclaimer that I am not an expert in interoperability between C and FORTRAN.
I have my main program in FORTRAN (GNU FORTRAN compiler). It needs to call a C dll for some calculations. However, the C dll needs to call another 3rd party dll which is written in FORTRAN. So basically the line of calls is:
Main FORTRAN Program --> C dll --> 3rd party FORTRAN dll.
I am not able to get this to work at all. I am not able to get any more debug information. The only error I see is "Program received signal SIGSEGV, Segmentation fault."
The Main FORTRAN --> C dll works fine. I tested by commenting the call to the FORTRAN dll.
I further did the following:
Test Program C++ --> C dll --> 3rd party FORTRAN dll.
The above case works perfectly fine. So it forces me to conclude that the error is due to the calling sequence from FORTRAN --> C --> FORTRAN
My question is, is there any special consideration for such a calling sequence?
Thanks for the help.
Regards, snkp
Edit: Problem Code
Fortran part
!Interface declaration
INTERFACE
SUBROUTINE SetupProgram(Num,NumComponents,ComponentConc,ConcPhase,ErrNum,Name,hr,herr,hfm)BIND(C,NAME='SetupProgram')
USE ISO_C_BINDING
INTEGER(kind=C_LONG), VALUE :: Num
INTEGER(kind=C_LONG) :: NumComponents
REAL(kind=C_DOUBLE),DIMENSION(20) :: ComponentConc
INTEGER(kind=C_LONG) :: ConcPhase
INTEGER(kind=C_LONG) :: ErrNum
CHARACTER(kind=C_CHAR),DIMENSION(20) :: Name
CHARACTER(kind=C_CHAR) :: hr
CHARACTER(kind=C_CHAR) :: herr
CHARACTER(kind=C_CHAR) :: hfm
END SUBROUTINE
END INTERFACE
!Main Fortran
PROGRAM Simulator
USE iso_c_binding, ONLY : c_ptr,c_double,c_f_pointer,C_INT,C_LOC,C_CHAR,C_NULL_CHAR
INTEGER(kind=C_INT) ID !ID
INTEGER(kind=C_LONG) :: NumComponents
REAL, DIMENSION(20) :: ComponentConc
INTEGER(kind=C_LONG) :: CompositionPhase
INTEGER(kind=C_LONG) :: ErrNum
CHARACTER(kind=C_CHAR,LEN=3) :: hr1 = ''
CHARACTER(kind=C_CHAR,LEN=255) :: herr1 = ''
CHARACTER(kind=C_CHAR,LEN=255),DIMENSION(20) :: Name1 = ''
CHARACTER(kind=C_CHAR,LEN=255) :: hfm1 = ''
CALL SetupProgram(ID,NumComponents,ComponentConc,CompositionPhase,ErrNum,Name1,hr1,herr1,hfm1)
END PROGRAM
C Part
//Header File
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_IMPORT __declspec(dllimport)
#endif
//#ifdef __cplusplus
extern "C"
{
//#endif
void DLL_EXPORT __cdecl SetupProgram(int Num,long& NumComponents,double ComponentConc[],long& ConcPhase,long& ErrNum,
char* Name,char hr[],char herr[],char hfm[]);
}
typedef void (__stdcall *fp_SETUPdllTYPE)(long &,char*,char*,char*,long &,char*,long ,long ,long ,long ); //char
extern fp_SETUPdllTYPE SETUPdll;
const long propcharlength=255;
const long lengthofreference=3;
const long errormessagelength=255;
const long nmax=20;
//cpp file
fp_SETUPdllTYPE SETUPdll;
void DLL_EXPORT __cdecl SetupProgram(int Num,long& NumComponents,double ComponentConc[],long& ConcPhase,long& ErrNum,
char* Name,char hr[],char herr[],char hfm[]);
{
strcpy(hfm,"123.abc");
strcpy(hr,"DEF");
strcpy(herr,"OK");
switch (Num){
case 1:
NumComponents = 1;
strcpy(Name,"123.abc");
ComponentConc[0]=1.0;
ConcPhase = 1;
break;
case 2:
NumComponents = 1;
strcpy(Name,"321.cba");
ComponentConc[0]=1.0;
ConcPhase = 1;
break;
case R410A:
NumComponents = 3;
strcpy(Name,"12.abc");
strcat(Name,"|34.abc");
strcat(Name,"|56.dca");
ComponentConc[0] = 0.6;
ComponentConc[1] = 0.4;
ComponentConc[2] = 0.0;
ConcPhase = 1;
break;
default:
NumComponents = 1;
strcpy(Name,"321.cba;
ComponentConc[0]=1.0;
ConcPhase = 1;
break;
}
SETUPdll(NumComponents, Name,
hfm, hr, ErrNum, herr,
propcharlength*nmax, propcharlength,
lengthofreference, errormessagelength);
}
When I comment out the SETUPdll call from the cpp file then FORTRAN calls the c++ dll correctly and gets all the character and long variables. As soon as I uncomment the SETUPdll call the program is not successful anymore.
I hope this helps.
Regards snkp