0

I am tasked with porting a legacy software, to a Managed Language.

A few of the hard-coded calculation models are extremely time consuming to port, without gaining anything in terms of features or performance from a full port.

We decided to make a C++/CLI wrapper instead.

i.e. something like this:

FortranLib.h:

#pragma comment(lib, "fortranlibrary.lib")

extern "C" {
    void SUBROUTINENAME(int * param1, int * param2, float * param3, int * returnCode);
}

using namespace System;

namespace FortranlibraryWrapper {
    public ref class FortranLib{
        public:
            enum class ReturnCodes : int{
               ok = 0,
               //... and so on and so forth
            }

            ReturnCodes SubRoutineName(int param1, int param2, float param3);
    }
}

FortranLib.cpp:

#include "stdafx.h"
#include "FortranLib.h"
namespace FortranlibraryWrapper {

    FortranLib::CalculationReturnCodes FortranLib::SubRoutineName(int param1, int param2, float param3)
    {
         int returnCode = -1;
         SUBROUTINENAME( &param1, &param2, &param3, &returnCode);
         return (ReturnCodes)returnCode;
    }
}

We have in the actual code tried to bound params 1-3 to avoid issues, but apparently we are not good enough, as we recently we saw this type of error come up, in a new test case:

Intel(r) Visual Fortran run-time error

forrtl: severe (408): fort: (3): Subscript #1 of the array ....

This is due to some calculation in the fortran code, that determines an array index. but the calculated index is outside the bounds of the array.

The problem is that the error comes as an error dialogue, and does not raise an exception. We have already tried this:

         int returnCode = -1;
         try{
             SUBROUTINENAME( &param1, &param2, &param3, &returnCode);
         }
         catch(...)
         {
             throw gcnew System::Exception("fortran runtime error??");
         }
         return (ReturnCodes)returnCode;

and found that it does not catch anything..

The new application is intended as a server based service, so I need to somehow capture this error, and log it, and ideally continue the service, and discard the job that caused the failure.

Does anyone know how to accomplish that?

I would prefer not editing the fortran code, and recompiling it, as I am a novice with that language.

Henrik
  • 2,180
  • 16
  • 29
  • The only real hope you have is that this actually generates an SEH exception, visible in the Output window when you debug. And that you forgot to compile with /EHa, required. – Hans Passant Aug 10 '17 at 14:11
  • Obviously, Fortran has no idea about C++ exceptions. And that error is raised by the compiler's runtime. You might be able to hijack it if it is not linked statically. – Vladimir F Героям слава Aug 10 '17 at 14:52
  • @Hans Passant, thank you, I researched it, and "Unfortunately, Intel® Fortran does not include extensions for SEH" https://software.intel.com/en-us/node/678483 – Henrik Aug 11 '17 at 06:20
  • @Vladimir, you are correct hat it's coming from the runtime. When you say hijack, do you have any idea on how that could be accomplished? - should one inject code into the runtime lib file, before linking? or.. – Henrik Aug 11 '17 at 06:23
  • See https://stackoverflow.com/questions/19596375/intercepting-fortran-stop-from-c – Vladimir F Героям слава Aug 11 '17 at 06:26
  • @ Vladimir F, thank you for the investigation, it may be a solution, however with the current build, the `stop` is done in the runtime library, _after_ the error message is shown, so someone has to press the ok button, for any of the examples in that question will work.. Perhaps I can set a compiler flag, to show the error in a console, instead of a popup window.. – Henrik Aug 11 '17 at 09:01

0 Answers0