- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个数千行的应用程序,它依赖SIGFPE(由传递给signal()的函数指针处理)来更改状态,并在某些浮点条件发生时使代码正确运行。但是,在托管模式下的C++/CLI下,_control87生成在用C编写的静态库中执行的System.ArithmeticException。不支持_fpreset和_control87。
如何使经典的,不受管理的SIGFPE操作在C++/CLI应用程序中工作?在我的应用程序中发生浮点运算的位置可能很多,而且我还不完全理解其他程序员几年前编写的所有数值方法。
我希望老式的异常处理能够将浮点数除以零,而不是INF值。平台调用样式不起作用,并且#pragmamanaged(off)也不起作用。
我有什么选择?
最佳答案
这里有几个非常严重的痛点。启用浮点异常与托管代码执行完全不兼容。简而言之,您可以轻松使JIT编译器崩溃。使用_control87()时,您要解决的问题是哪一个。
是的,您将获得CLR异常,每当它执行 native 代码时,它将放置一个异常支持。仅在引发异常并且没有代码可处理时,才调用信号处理程序。 CLR不可避免地会在C运行时库看到该异常之前就看到该异常。因此,您将永远不会收到SIGFPE处理程序调用。
唯一可行的解决方法是编写一个包装,以便在CLR之前捕获异常。仔细管理FPU控制字也非常非常重要,您只能承受在运行 native 代码时启用FPU异常的能力。这需要一堆坚韧的代码,预先警告您将不会非常喜欢它。
您没有发布任何代码段,因此我必须组成一个愚蠢的示例:
#include <Windows.h>
#include <signal.h>
#include <float.h>
#pragma managed(push, off)
double divisor;
void __cdecl fpehandler(int sig) {
divisor = 1.0;
}
double badmath() {
divisor = 0.0;
return 1 / divisor;
}
#pragma managed(pop)
// Exception filter in the CRT, it raises the signal
extern "C" int __cdecl _XcptFilter(unsigned long xcptnum,
PEXCEPTION_POINTERS pxcptinfoptrs);
int FloatingpointExceptionFilter(unsigned long xcptnum, PEXCEPTION_POINTERS pxcptinfoptrs) {
// Only pass floating point exceptions to the CRT
switch (xcptnum) {
case STATUS_FLOAT_DIVIDE_BY_ZERO:
case STATUS_FLOAT_INVALID_OPERATION:
case STATUS_FLOAT_OVERFLOW:
case STATUS_FLOAT_UNDERFLOW:
case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_INEXACT_RESULT:
case STATUS_FLOAT_STACK_CHECK:
case STATUS_FLOAT_MULTIPLE_TRAPS:
case STATUS_FLOAT_MULTIPLE_FAULTS:
return _XcptFilter(xcptnum, pxcptinfoptrs);
break;
default:
return EXCEPTION_CONTINUE_SEARCH;
}
}
double badmathWrapper() {
__try {
return badmath();
}
__except (FloatingpointExceptionFilter(GetExceptionCode(), GetExceptionInformation())) {
}
}
using namespace System;
using namespace System::Runtime::CompilerServices;
public ref class Wrapper {
public:
static double example();
};
[MethodImplAttribute(MethodImplOptions::NoInlining)]
double Wrapper::example() {
signal(SIGFPE, fpehandler);
_clear87();
unsigned oldcw = _control87(_EM_INEXACT, _MCW_EM);
try {
return badmathWrapper();
}
finally {
_control87(oldcw, _MCW_EM);
signal(SIGFPE, nullptr);
}
}
关于floating-point - C++/CLI : SIGFPE, _control87,_fpreset,将古老的不受管理的Watcom C应用程序移植到.NET,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3338534/
列表项 我的 config/routes.rb 文件... Rails.application.routes.draw do namespace :api, defaults: {format:
我是一名优秀的程序员,十分优秀!