2013-03-15 29 views
4

我正在从C++调用Fortran 77函数来传递文件句柄,字符串和长度。文件成功打开,并且Fortran子例程退出。但是,在C++代码中,传递给fortran的字符串已损坏。当函数openFile的底部到达时,程序崩溃。从C++调用Fortran;返回字符串损坏

该崩溃只出现在版本中,但不在调试中。绘制字符串,我看到在释放变量fileNameToFortran充满垃圾。

感谢您的帮助

我用ifort与下面的编译器标志在释放(Windows 7计算机(32位)): /名称:小写/ f77rtl /回溯/ IFACE:CREF /线程/递归/ LD

,并在调试: /名称:小写/ f77rtl /回溯/ IFACE:CREF /线程/递归/ LDD /紫/调试:全/检查:所有/回溯


这里是C代码:

typedef void (FORTCALL *sn_openfile_func) (int *, 
              char[], 
              int *, 
              int); 
void openFile(const int fileHandle, const std::string fileName) 
{ 
    int fileHandleToFortran = fileHandle; 
    char fileNameToFortran[20]; 
    assert(fileName.size() < 20); 

    strcpy(fileNameToFortran, fileName.c_str()); 
    int lstr = strlen(fileNameToFortran); 
    openfile_func_handle(&fileHandleToFortran, fileNameToFortran, &lstr, lstr); 
} 

这里是Fortran代码:

 SUBROUTINE SN_OPENFILE(FILENR,FILENAME,FSIZE) 
     !DEC$ ATTRIBUTES DLLEXPORT :: SN_OPENFILE 
     IMPLICIT NONE 
     INTEGER FILENR, FSIZE 
     CHARACTER FILENAME*FSIZE 
     OPEN (FILENR,FILE = FILENAME, 
    &  ACCESS = 'SEQUENTIAL' , STATUS = 'REPLACE', ERR=222) 
     GOTO 333 
222 WRITE(*,*) 'Error opening file' 
333 END 
+0

Fortran例程调用的地方在哪里?它是'openfile_func_handle'吗?在这种情况下,为什么哟传递4个参数,而'ṠN_OPENFILE'只能期望3? – 2013-03-15 12:07:30

+4

在这个时代,我将使用Fortran ISO C Binding来混合使用C/C++和Fortran。这提供了一种接口语言的标准方式,而不必找出特定编译器的调用约定,例如将字符串长度添加到参数列表的末尾。这些公约是不可移植的,并且可能会发生变化。大多数Fortran 95编译器都有这个特性,这是Fortran 2003的一部分。(甚至除了想要使用ISO C绑定之外,我还会使用Fortran 95/2003而不是FORTRAN 77.)ifort和gfortran手册中有示例;这里也有问题。 – 2013-03-15 13:07:10

+0

请参阅下面的答案。感谢您的努力。 – Fady 2013-03-15 15:26:15

回答

1

OK,我发现自己的答案。

宏FORTCALL被定义为__STDCALL 现在,当使用iface:cref时,它只会在发布时崩溃。这很奇怪,但是在我删除它之后,它可以用于发布和调试。

+1

另一个理由是使用M.S.B建议的Fortran的ISO C绑定特性。这应该有希望没有任何大惊喜的工作。 – 2013-03-16 06:36:10