11

My WPF test app (very simple, just one window) is using a 3rd party managed dll (say X.dll). This managed dll uses some unmanaged dll's . So lets say I write a small wpf app which just references X.dll. And in the window's constructor I access something inside X.dll (ie. in some namespace in X.dll). On doing this i dont catch any exception and it seems like things are going on as expected. But upon returning the control to .NET runtime, I get an exception in Application class's 'DispatcherUnhandledException' handler :

“Overflow or underflow in the arithmetic operation.” System.ArithmeticException was unhandled Message="Overflow or underflow in the arithmetic operation."
Source="PresentationFramework"
StackTrace:

System.Windows.Window.ValidateTopLeft(Double length)
System.Windows.Window.CoerceTop(DependencyObject d, Object value) System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean skipBaseValueChecks)
System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
System.Windows.DependencyObject.CoerceValue(DependencyProperty dp) at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
System.Windows.Window.CreateSourceWindowImpl() at System.Windows.Window.SafeCreateWindow() at System.Windows.Window.ShowHelper(Object booleanBox)
System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

Some points:

  • This only occurs in WPF app and not in winforms app.
  • This does not get caught in a try-catch. only in Application's DispatcherUnhandledException
  • This does not happen if I access X.dll's code inside the Window's 'Loaded' event, only happens in constructor.

Can anyone guess the problem ?

Thanks, Mishal

mishal153
  • 1,498
  • 3
  • 26
  • 37
  • When you say "access", you mean that you're passing the value as an argument to something, right? To what are you passing it? – Jay Mar 09 '10 at 18:15
  • If I access/read the integer XNameSpace.AStaticClass.StatInt (where XNamespace is a namespace inside X.dll) and store it in another integer, i see this. Moreover, i see that if I put the statement in try catch then it does not get caught. It gets caught only in the System.Window.Application's DispatcherUnhandledException handler....thats really weird. – mishal153 Mar 11 '10 at 15:09

3 Answers3

14

Following the link from @Mishhl the fix is

public class FloatingPointReset
{
    [DllImport("msvcr110.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int _fpreset();


    public static void Action()
    {
        // Reset the Floating Point (When called from External Application there was an Overflow exception)
        _fpreset();
    }
}

It's caused by something in an included DLL resetting the FP into a state that isn't compatible with WPF/C#/Microsoft DLL's. Delphi/CPPB does this by default.

So in either the window constructor or App() constructor just do

FloatingPointReset.Action();

You may need to change the following to reference any version of msvcr###.dll

[DllImport("msvcr110.dll", CallingConvention = CallingConvention.Cdecl)]

e.g.

[DllImport("msvcr70.dll", CallingConvention = CallingConvention.Cdecl)]
Richard Harrison
  • 19,247
  • 4
  • 40
  • 67
  • 1
    My suggestion is to call _fpreset not only in constructor but before and after external functions calls. I have this problem when calling functions from 3rd part COM-object library. – Denis Dec 11 '15 at 04:37
  • For me I solved it by following the external library I'm using and knew which msvcrXX.dll it's using (it was msvcr100.dll), then I called **FloatingPointReset.Action();** right before calling **base.OnRender(drawingContext);** in my UserControl. – Dabbas Apr 11 '17 at 17:13
  • @Dabbas How to determine the msvcrxx.dll version an external DLL is using? – JeeShen Lee Jan 27 '22 at 02:50
7

I am not sure of the root cause yet but the solution is here :
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a31f9c7a-0e15-4a09-a544-bec07f0f152c

Seems to be a popular bug :)

thanks, Mishal

mishal153
  • 1,498
  • 3
  • 26
  • 37
  • Just for others sake, the proposed solution in the link is more along the lines of a workaround. The problem itself seems to be a bug in WPF although I'm not sure if there is a connect issue yet on this one. – jpierson May 01 '14 at 01:52
  • https://connect.microsoft.com/VisualStudio/feedback/details/382052/cryptic-arithmeticexception-in-system-double-equals-during-wpf-layout – jpierson May 01 '14 at 01:58
3

If it can help, I was having the exact same problem (as stated here and here). I bring here one of the possible CAUSE of this.

I am using a ElementHost (c#, .net4.0, winform, VS2012) for a great WPF UserControl. Everything was working Great. In my UserControl behind-code, I was using a class that was caming from another DLL, used to store progression of certain task. For example (it is close to reality) :

public class SI_MyProgressionHelper
{
    public string gstr_OverallProgress_Description { get; set; }

    public int gint_OverallProgress_ActualValue { get; set; }
    public int gint_OverallProgress_MaximumValue { get; set; }
}

I then wanted to "plug" that class into my WPF progressBar/textBox to report the progression as it goes. However (and that's another conversation), WPF needs to have INotifyPropertyChanged applied to every single property you want to plug in WPF (to automatically update controls in WPF). That's one of the ugliest thing I ever saw, but it is what it is (And I know i must missed something..)

Anyway, to complies to WPF Binding mecanism between my ProgressBar/textbox and my SI_MyProgressionHelper class, i've modified the class (which I repeat, is in another DLL) to this :

public class SI_MyProgressionHelper : INotifyPropertyChanged
{
    private string _gstr_OverallProgress_Description = "";
    public string gstr_OverallProgress_Description { get { return _gstr_OverallProgress_Description; } set { _gstr_OverallProgress_Description = value; RaisePropertyChanged("gstr_OverallProgress_Description"); } }   

    private int _gint_OverallProgress_ActualValue = 0;
    public int gint_OverallProgress_ActualValue { get { return _gint_OverallProgress_ActualValue; } set { _gint_OverallProgress_ActualValue = value; RaisePropertyChanged("gint_OverallProgress_ActualValue"); } }   

    private int _gint_OverallProgress_MaximumValue = 9999;
    public int gint_OverallProgress_MaximumValue { get { return _gint_OverallProgress_MaximumValue; } set { _gint_OverallProgress_MaximumValue = value; RaisePropertyChanged("gint_OverallProgress_MaximumValue"); } }   


    protected virtual void RaisePropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

BAM! The error occurs on any random integer property of any XMLElement (Height, Width, etc...) of my UserContrl (exactly as stated here and in the other reference I stated at the top).

Applying the solution brought here does correct my problem : In my Program.cs Main() method :

[DllImport( "msvcr70.dll", CallingConvention = CallingConvention.Cdecl )]
public static extern int _fpreset();

and then, in my UserControl.xaml.cs, in the constructor :

public UserControl1()
{
    Program._fpreset(); 
    InitializeComponent();
} 

Also, and that's the reason why I wrote that comment : by removing the INotifyPropertyChanged on my Helper class (and other stuff related), the problem goes away. (but my WPF is sad because my code is too short for him).

Hope this additionnal information may help someone having the same problem.

Also, for all my french colleague, here is the french error encountered :

Il y a eu un dépassement de capacité positif ou négatif dans l'opération arithmétique.

Simon
  • 2,266
  • 1
  • 22
  • 24
  • I'm getting the same error, but I'm not using msvcr70.dll. Is it possible to find out which DLL cause similar errors? and how? – JeeShen Lee Dec 03 '21 at 03:33