1

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

snkp
  • 43
  • 7
  • Do you have any code? The special thing for this sequence is only to use the modern C-Fortran interoperability http://gcc.gnu.org/onlinedocs/gcc-4.9.0/gfortran/Interoperability-with-C.html – Vladimir F Героям слава May 02 '14 at 18:42
  • I added part of the code that demonstrates the issue. – snkp May 02 '14 at 19:22
  • I always avoid passing characters string to/from `FORTRAN` as they never work as intended. – John Alexiou May 02 '14 at 19:43
  • Add IMPLICIT NONE to your interface bodies and other scopes, fix the resulting errors, then see how you go. – IanH May 02 '14 at 22:15
  • @ja72, I am able to successfully pass and get the character strings in return. The values returned are correct. Also for the information, I use LoadLibrary to load the dll. – snkp May 03 '14 at 00:04
  • @IanH, Adding IMPLICIT NONE did not help. Out of curiosity, why do you think that would make any effect? – snkp May 03 '14 at 00:09
  • Sometimes a `dll` goes through fine, but there is still a stack imbalance which leads to seg faults. Don't be so certain that your `C->FORTRAN` is perfect unless you prove it with some deep memory and stack tracing. – John Alexiou May 03 '14 at 03:09
  • If adding IMPLICIT NONE in the interface body didn't raise any errors, then the code you've posted is not the code you are compiling. In the interface body you have an argument that is not declared (`Name`). In the main program, what is `FluidName`? In the main program there are numerous things that are not declared. Many of the character arguments in the interface body are declared to be length 1. You call the procedure perhaps with LEN=255 things. Is that intentional? – IanH May 05 '14 at 13:20
  • @IanH, Sorry I pasted from my working files into a single file since many variables are declared in a global module. In the process I guessed, I missed a few. I edited the code. – snkp May 05 '14 at 17:15

0 Answers0