挖井

类库大魔王的挖井日记

挖一口属于自己的井


嵌入的CLR引用销毁的C++对象的问题续

  前面的blog中,网友sali98提到可以用#pragma init_seg(compiler)等来安排全局对象的构造和析构顺序。这倒是我以前没有想到的,不过经过实际测试后,发现这个方案并不能解决我的问题。
  在原来的定位结果中,以为单纯是嵌入的CLR对象晚于C++对象的销毁引起的问题,实际上问题要稍微复杂一点。首先,上次提到的使用_exit引起的对象无声息的消失,不是主要问题。这里调用_exit是在之前有个人把exit换掉的结果,他以为_exit不会调用对象的析构函数,于是不会引起析构时资源销毁时机不正确的问题。事实上这个fix是不起作用的,因为从call stack来看,_exit对嵌入的CLR似乎不起那个作用,而且无论是exit还是_exit都会在对象正常或不正常销毁后仍然有消息循环存在,消息循环中某些处理代码仍然会继续运行,而那些代码也是有可能会引用已消失的singleton的。
  最早我想的解决方案是基于这样的想法,既然是C++的singleton在被销毁后没经检验就来使用,那么就把singleton改好一点就行了,我想过《Modern C++ Design》中提到的Phoenix Singleton,也看过一些boost中的Singleton的实现。不过后来都感觉太麻烦,没必要。于是今天试了一个很简单的方法,增加一个static bool变量,标记当前singleton是否有效,然后在每个非static的method开头都先判断一下。简单测试一下,倒是能勉强工作了,不过发现另外一个问题,这样的singleton不止一个!而且另一个不好的地方是,每个非static的method都要修改一下,不必要的改动太多。
  今天又看了一下crash的call stack,我就觉得单纯修改singleton的实现似乎不是很高效。于是我就想,是不是有办法在调用exit或_exit前就自己写代码把CLR卸载掉,把消息循环停掉?以我对.NET的粗浅的了解,我觉得嵌入的CLR是应该可以主动卸载掉的,只不过也许某些正在使用的资源会成为阻碍,这个要仔细调研一下。而停掉消息循环这个,感觉也是可以的,增加个标记,在消息循环里判断一下,可以自己主动跳出循环。

本文地址:

https://minidump.info/blog/2012/02/e5-b5-8c-e5-85-a5-e7-9a-84clr-e5-bc-95-e7-94-a8-e9-94-80-e6-af-81-e7-9a-84c-e5-af-b9-e8-b1-a1-e7-9a-84-e9-97-ae-e9-a2-98-e7-bb-ad/

上一篇

编译了GDIPP

  前两天才知道GDIPP是LGPL的,放在googlecode上。昨天把它所有的源代码clone下来了,然后编译了一下,倒是全部编译出来了,不过运行后貌似没什么效果,囧了,有空读一下它的源代码。众所周知Windows的字体渲染效果不怎么样,所以对于自己有一套效果良好的字体渲染手段是很有吸引力...…

Software 全文阅读
下一篇

Ninayan W.I.P.(29)

  这两天又重新拾起Ninayan来,随着embed.ly的收费,Ninayan的主打的图片、视频浏览功能被废掉了,只好自己写代码来实现这部分了,但这工作量应该比较大,只能慢慢来了,有点想把这部分代码做成开源项目,叫SANSASORI。  之前也有断断续续地修改,支持Follow5,后来Fol...…

Ninayan 全文阅读