首先是免责声明,我不是C和FORTRAN之间互操作性的专家。
我在FORTRAN(GNU FORTRAN编译器)中有我的主程序。它需要调用C dll进行一些计算。但是,C dll需要调用另一个用FORTRAN编写的第三方dll。所以基本上调用的是:
主要FORTRAN计划 - > C dll - >第三方FORTRAN dll。
我根本无法使用它。我无法再获得调试信息。我看到的唯一错误是"程序收到信号SIGSEGV,分段错误。"
主要FORTRAN - > C dll工作正常。我通过评论对FORTRAN dll的调用来测试。
我进一步做了以下事情:
测试程序C ++ - > C dll - >第三方FORTRAN dll。
上述情况完全正常。所以它迫使我得出结论,错误是由于来自FORTRAN的调用序列 - > C - > FORTRAN
我的问题是,对这样的呼叫序列有什么特别的考虑吗?
感谢您的帮助。
此致 snkp
编辑:问题代码
Fortran部分
!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部分
//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);
}
当我从cpp文件中注释掉SETUPdll调用时,FORTRAN正确调用c ++ dll并获取所有字符和长变量。一旦取消注释SETUPdll调用,程序就不再成功。
我希望这会有所帮助。
此致 snkp