所有windows api都被标记为nothrow了?

tomqyp 2012-11-18
终于开始玩D2了,拿着dfl编译一下,报一堆错,在其中一个nothrow有关的错误上转了半天。

google了一下在
https://github.com/D-Programming-Language/druntime/pull/225
找到了原因:
core.sys.windows.windows: add nothrow, pure, and some functions (already merged: 2886846)

mark all WinAPI functions as nothrow
mark all extern(D) macros-functions as pure
add WinAPI functions from std.process

可是问题来了,自身的非nothrow的callback函数怎么传给windows api?我的解决办法是把callback标记为nothrow,然后try,catch住里面的内容,可是这个样就再来了新问题,catch中不能throw异常,否则编译器继续报错。
即使windows的代码都没问题也不能保证自己的callback一点问题也没有啊?这样还怎么抓错?
另外,要是自己或者引用的库自定义了定义了api的原型,那么就不是nothrow了吧?可是这样代码不是变成两种标准了吗?

大家是怎么解决这样问题的呢?
非仙 2012-11-19
你对异常理解有误
callback中出错异常是SEH,和c++异常无关,不能被try到的
api中明显不会抛出异常的 声明为nothrow是正确的
tomqyp 2012-11-19
谢谢 这么说D的try不能catch到SEH异常了吗?
但是我记得昨天晚上扫了一眼std.exception的代码,里面好像是有对SEH链的处理,不过没仔细看,呆会下班看看
tomqyp 2012-11-20
实在是静不下心来看D异常的实现,刚刚看了看rt部分的代码,D的异常貌似也是用SEH来实现的,也就是说windows的SEH机制是可以捕获D的未处理异常的。

像SetTimer这类api的callback中可能会执行任何D代码,可能会调用任何第三方的D库,如果有一个未处理的异常,如果没有nothrow标记的话windows的SEH机制会捕获这个异常,然后给一个提示。为了适应nothrow用try,catch拦住所有未知异常的话,那就必需自己来处理这些异常了,否则,有了问题就很难找头绪了。
非仙 2012-11-21
不管是不是nothrow 声明 SEH机制都会有效 异常没有被处理的情况下 windows都会给出提示框
tomqyp 2012-11-21
非仙 写道
不管是不是nothrow 声明 SEH机制都会有效 异常没有被处理的情况下 windows都会给出提示框

对呀,但是标记为nothrow后,就callback中就必需自己把所有异常都拦下来,否则就编译不过去了。

说者说是不是应该这么理解,D2认为用户在所有windows api的callback中应该自己处理所有可能的异常,而不是让windows来弹提示框?
非仙 2012-11-22
tomqyp 写道
非仙 写道
不管是不是nothrow 声明 SEH机制都会有效 异常没有被处理的情况下 windows都会给出提示框

对呀,但是标记为nothrow后,就callback中就必需自己把所有异常都拦下来,否则就编译不过去了。

说者说是不是应该这么理解,D2认为用户在所有windows api的callback中应该自己处理所有可能的异常,而不是让windows来弹提示框?

所有语言都是这样的,windows是最后一步,弹了提示框 点了之后必然是退出进程了
tomqyp 2012-11-23
非仙 写道

所有语言都是这样的,windows是最后一步,弹了提示框 点了之后必然是退出进程了

所以说这个是个D2的不同之处了呀。
api成了nothrow,我们的callback就必需拦下所有未处理异常,这样我们就面临两个选择。
要么拦下后什么都不做,这样省事,但是就失去了找出问题的机会。
要么拦下后,自实现windows已有的功能,弹提示或者记录错误信息。

其实这两天我想了想这样也没什么不好,D2把所有api标记为nothrow就逼得我们不得不在callback中处里所有未知异常,这样至少比windows默认的未处理异常的提示框对用户而言最友好一些。

另处我想如果自已重申明一下这些api或者干脆把windows.d从phobos中拷出来改个model名应该就可以绕过它的限制了吧,我还没试过,不过这样应该也有弊端,比如有其它D库如果引用了phobos中windows声明,编译时可能会报符号重名的错。
Global site tag (gtag.js) - Google Analytics