- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
Thanks,
Walter Kramer
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page