Sorry to ask yet another question!
I have a routine in Fortran that has been compile as CVF (as the version of NAG requires the CVF calling convention) below:
LOGICAL*4 FUNCTION set_process_name (name, len1) !DEC$ATTRIBUTES ALIAS : '_SET_PROCESS_NAME@8' :: set_process_name IMPLICIT NONE CHARACTER name*32 INTEGER*4 len1, len2 INTEGER*4 i LOGICAL*4 fin ProcessName = "" fin = .FALSE. DO i = 1, 32 IF ((Name(i:i) .GT. ACHAR(0)) .AND. (fin .EQ. .FALSE.)) THEN ProcessName(i:i) = Name(i:i) ELSE fin=.TRUE. END IF END DO set_process_name = .TRUE. RETURN END
The Fortran settings are
/nologo /debug:full /Od /I"Debug/" /I"..\Incl/" /I"C:\build\Intel Fortran RTO+ Calculation Engine\Sources\Solve\Debug/" /reentrancy:threaded /extend_source:132 /fpscomp:nolibs /debug-parameters:used /warn:declarations /warn:ignore_loc /fpe:1 /fp:source /names:uppercase /iface:cvf /module:"Debug/" /object:"Debug/" /Fd"Debug\vc140.pdb" /traceback /check:stack /libs:dll /threads /dbglibs /winapp /c
This Fortran routine called by a routine that is located inside an C++ MFC OLE Server compiled using stdcall as the default calling convention.
BOOL Application::SetProcessName(LPCTSTR p_Name) { long lDum = 0; TRY { if (strncmp(p_Name, "###", 3) == 0) { LPCTSTR m_Name; m_Name = &p_Name[3]; MonitorServer = (char *) malloc (strlen(m_Name) + 1); strcpy (MonitorServer, m_Name); } else { if (ProcessName == NULL) { free (ProcessName); } ProcessName = (char *) malloc (strlen(p_Name) + 1); // ----------------------------------- // Set the process name in the fortran // ----------------------------------- SET_PROCESS_NAME(p_Name, &lDum); strcpy (ProcessName, p_Name); } return TRUE; } CATCH_ALL (e) { THROW_LAST(); } END_CATCH_ALL return FALSE; }
The settings for the C++ are
/FR".\Debug\" /GS- /analyze- /W3 /Gy /Zc:wchar_t- /I"..\HysysLink/" /I"..\DXSConnect/" /ZI /Gm /Od /Fd".\Debug\" /Zc:inline /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MT" /D "_VC80_UPGRADE=0x0600" /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gz /Oy- /MDd /Fa".\Debug\" /EHsc /nologo /Fo".\Debug\" /Fp".\Debug\RtoOle.pch"
The Fortran routine is declared in C++ as
extern "C" long __stdcall SET_PROCESS_NAME(LPCTSTR, long *);
After the ' return FALSE' line is executed the CheckESP raises an exception 'Run-time check failure 0 - T'.
The call stack is below
RtoOle.exe!failwithmessage(void * retaddr, int crttype, int errnum, const char * msg) C++
RtoOle.exe!_RTC_Failure(void * retaddr, int errnum) C++
RtoOle.exe!_RTC_CheckEsp() C++
> RtoOle.exe!Application::SetProcessName(const char * p_Name) Line 5654 C++
[External Code]
RtoOle.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 26 C++
[External Code]
I thought that setting the calling convention in C++ for the Fortran routine is all that is needed to ensure that the routine is called properly with the correct stack handling.