Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29280 Discussions

error handling in dll called from excel

wkramer
Beginner
707 Views
Hello,

I have several functions residing inside a dll that are called from excel.
Excel starts recalculting all calls to these functions if I change the value of one field.
I for some reason a floating point error occurs in a function, then another function (in which no error occured) also jumpes to the error label I defined with "On Error Goto" in VBE.
The calculation and result of this other function are OK (which I found out by stepping through the code), but for some reason the error is still "active" on return from the dll, and so execution is passed to the statement following the error label.
I tried to solve this by adding a error handling routine to the dll with a call to signalqq in dllmain. But this doesn't function. The error handling in the dll is ignored.

Does anyone have an idea about what is happening and how I can solve the problem.
I would prefer not to add numerous checks inside the code to pass an error back from a deeply nested function to the highest level routine.

Thanks,

Walter Kramer
0 Kudos
5 Replies
gfthomas8
Novice
707 Views
It looks to me that you're trying to get vba to do exception handling on behalf of the dll, which is not all together sporting.

I might be able to help if you could answer the following:
Are the errors fp exceptions or runtime math lib errors?
Why not post your DllMain?
Why is signalqq called from DllMain?
Is the control word for the dll the same as it is for excell? If not, how do they differ?
Are you supplying a replacement matherrqq?

Ciao,
Gerry T.
0 Kudos
wkramer
Beginner
707 Views
I get an "overflow" error message

Signalqq is called from Dllmain, because I expected that initialization of the dll was the proper moment to install a floating point error handler.
The call to signalqq in dllmain returns with 0.
The function hand_fpe is never entered.

I am not supplying a replacement matherrqq.

I don't know what you exactly mean by the control word. How do I retrieve this to make the check?
I could get the instance handle from Dllmain if you mean that, but I dont know how to do this from excel.

Dllmain looks like this:

      integer(4) function DllMain(hInst,
     &                            ul_reason_being_called,lpReserved)
      !DEC$ IF DEFINED(_X86_)
      !DEC$ ATTRIBUTES STDCALL, ALIAS : '_DllMain@12' :: DllMain
      !DEC$ ELSE
      !DEC$ ATTRIBUTES STDCALL, ALIAS : 'DllMain' :: DllMain
      !DEC$ ENDIF
          use Public
          use dflib
     
          implicit none
      
        ! Arguments
          integer(4) hInst
          integer(4) ul_reason_being_called
          integer(4) lpReserved
          integer(4) iret
          interface
            function hand_fpe (signum, excnum)
            !dec$ attributes c :: hand_fpe
              use asme_rst, only : sterflag
              integer(2), intent(in) :: signum, excnum
            end function
          end interface
      
        !  sig$fpe handler installed to handle floating point errors
          iret=signalqq(sig$fpe, hand_fpe)
        !  Return 1 to indicate success
          DllMain = 1
          return
      end function DllMain

      function hand_fpe (signum, excnum)
      !dec$ attributes c :: hand_fpe
        use asme_rst, only : sterflag
        integer(2), intent(in) :: signum, excnum
        sterflag = .true.
        hand_fpe = 1
      end function


Thanks,

Walter Kramer
0 Kudos
gfthomas8
Novice
707 Views
It's still not clear to me whether you'r handling fpe's in your own code or in the math lib run time, but no matter. Try the following:

1. Get rid of the DllMain. Invoke signalqq in the dll's 'main' entry point,eg,

integer(4) function Main

!Export entry point
!DEC$ ATTRIBUTES DLLEXPORT::Main
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_Main' :: Main
...
interface
function hand_fpe (signum, excnum)
end interface
...
iret=signalqq(sig$fpe, hand_fpe)
...
end function Main

Call 'main' from excel on a prn basis.

2. Note the !...! additions in your handler. Each time the dll invokes the handler, the fpu's status is cleared and this might keep excell from assuming a fpu left in an uncleared state by the dll.

function hand_fpe (signum, excnum)
!dec$ attributes c :: hand_fpe
use asme_rst, only : sterflag
!
USE DFLIB
IMPLICIT NONE
!
integer(2), intent(in) :: signum, excnum
sterflag = .true.
!
CALL CLEARSTATUSFPQQ
!
hand_fpe = 1
end function

3. Check that your handler works via RAISEQQ(SIG$FPE)
4. You could also wrap CLEARSTATUSFPQQ, export it, and call it from excel to reinitialize the fpu.

If the foregoing doesn't solve the problem I can muster up a sample that demonstrates how to get this kind of thing to work.

Ciao,
Gerry T.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
707 Views
Just a side note: if you're aliasing the routine, alias it properly, according to STDCALL specification, i.e. _Main@0. If you're using CVF 6.6, you can use STDCALL, ALIAS, DECORATE: "Main" to obtain default name mangling.

Jugoslav
0 Kudos
gfthomas8
Novice
707 Views
There are a couple of ways of aliasing according to __stdcall:


STDCALL, DECORATE, ALIAS : '_Main@0' :: 'Main'

or

STDCALL, ALIAS : '_Main' :: 'Main'

with an entry

EXPORTS
;Function Ordinal
;-------- -------
Main @1

in the dll's .def.
I consider the latter as the 'proper' approach for me especially when c++ functions have also to be exported.

Gerry T.
0 Kudos
Reply