c# - 从 dll 调用 C 函数后 C# 代码中的 ArithmeticException

标签 c# wpf dll arithmeticexception

我有用 C# 编写的代码和用 C 编写的 DLL。我正在尝试从 DLL 调用函数。例如 C 中 DLL 的头文件:

// ---------------------------------------------------------------------------
#ifndef Perspectiva_DLLUnitH
#define Perspectiva_DLLUnitH
// ---------------------------------------------------------------------------
#define DLL_EXPORT __export __stdcall
// ---------------------------------------------------------------------------
#ifdef __cplusplus
extern "C"
{
#endif
UCHAR DLL_EXPORT Init(ULONG TerminalID, CHAR *AzsNo, ULONG *Len);
...
#ifdef __cplusplus
}
#endif
// ---------------------------------------------------------------------------
#endif

这就是我在 C# 中使用这个 DLL 的方式:
static class Pers
{
   [DllImport("Perspectiva_DLL.dll", CallingConvention = CallingConvention.StdCall)]
   public static extern byte Init(uint TerminalID, string AzsNo, out uint Len);
   ...
}

...

uint Len = Convert.ToUInt32(AzsNo.Text.Length);
Pers.Init(Convert.ToUInt32(TerminalID.Text), AzsNo.Text, out Len);

函数 Init 正常工作并返回结果。但是在通话后,如果我尝试对界面进行任何操作,例如更改选项卡或只是单击文本框,我会遇到异常:ArithmeticException .

我不明白我的代码中的错误在哪里。

异常详情:
System.ArithmeticException was unhandled
  HResult=-2147024362
  Message=Переполнение или потеря точности в арифметической операции.
  Source=WindowsBase
  StackTrace:
       в System.Windows.Size..ctor(Double width, Double height)
       в System.Windows.Documents.AdornerLayer.InvalidateAdorner(AdornerInfo adornerInfo)
       в System.Windows.Documents.AdornerLayer.UpdateElementAdorners(UIElement element)
       в System.Windows.Documents.AdornerLayer.UpdateAdorner(UIElement element)
       в System.Windows.Documents.AdornerLayer.Add(Adorner adorner, Int32 zOrder)
       в System.Windows.Documents.CaretElement.EnsureAttachedToView()
       в System.Windows.Documents.CaretElement.Update(Boolean visible, Rect caretRectangle, Brush caretBrush, Double opacity, Boolean italic, CaretScrollMethod scrollMethod, Double scrollToOriginPosition)
       в System.Windows.Documents.TextSelection.UpdateCaretStateWorker(Object o)
       в System.Windows.Documents.TextSelection.UpdateCaretState(CaretScrollMethod caretScrollMethod)
       в System.Windows.Documents.TextSelection.EnsureCaret(Boolean isBlinkEnabled, Boolean isSelectionActive, CaretScrollMethod scrollMethod)
       в System.Windows.Documents.TextSelection.System.Windows.Documents.ITextSelection.UpdateCaretAndHighlight()
       в System.Windows.Documents.TextEditor.OnGotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
       в System.Windows.Controls.Primitives.TextBoxBase.OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
       в System.Windows.UIElement.OnGotKeyboardFocusThunk(Object sender, KeyboardFocusChangedEventArgs e)
       в System.Windows.Input.KeyboardFocusChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       в System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       в System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       в System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       в System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
       в System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       в System.Windows.Input.InputManager.ProcessStagingArea()
       в System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
       в System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
       в System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
       в System.Windows.Input.KeyboardDevice.Focus(DependencyObject focus, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
       в System.Windows.Input.KeyboardDevice.Focus(IInputElement element)
       в System.Windows.UIElement.Focus()
       в System.Windows.Documents.TextEditorMouse.MoveFocusToUiScope(TextEditor This)
       в System.Windows.Documents.TextEditorMouse.OnMouseDown(Object sender, MouseButtonEventArgs e)
       в System.Windows.Controls.Primitives.TextBoxBase.OnMouseDown(MouseButtonEventArgs e)
       в System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
       в System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       в System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       в System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       в System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       в System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
       в System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       в System.Windows.Input.InputManager.ProcessStagingArea()
       в System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
       в System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
       в System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
       в System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       в System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       в MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       в MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       в MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       в System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       в MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       в MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       в System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       в System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       в System.Windows.Threading.Dispatcher.Run()
       в System.Windows.Application.RunDispatcher(Object ignore)
       в System.Windows.Application.RunInternal(Window window)
       в System.Windows.Application.Run(Window window)
       в System.Windows.Application.Run()
       в Perspectiva_test.App.Main() в d:\тнп\test_codes\Perspectiva_test\Perspectiva_test\obj\Debug\App.g.cs:строка 0
       в System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       в System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       в System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

最佳答案

如果 C dll 的运行时系统更改了 FPU 标志,通常会发生这种情况。您需要在调用类似于此的函数后重置它们:

[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
extern static uint _controlfp(uint newcw,uint mask);

const uint _MCW_EM=0x0008001f;
const uint _EM_INVALID=0x00000010;

public static void FixFPU() {
{
  _controlfp(_MCW_EM, _EM_INVALID);
}

关于c# - 从 dll 调用 C 函数后 C# 代码中的 ArithmeticException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21091426/

相关文章:

c# - 如何获取 SelectedItem 的所有子项

c++ - 在 C 代码中为 Matlab/LabView 接口(interface)创建 DLL 包装器

c# - 我如何绘制 X?

c# - javascript单引号问题

c# - View 中的十进制验证

.net - 代码和 XAML 中图像 URI 行为的区别

c# - 使用 system.io.ports c# Windows IoT Universal

c# - 如何在 WPF 中动态更改 DataGridTextColumn 绑定(bind)上的转换器?

c# - 嵌入或引用项目

java - 手动加载 native 库以规避限制性环境