Languages

在Windows中加载组件的“998”错误

最近老是遇到这个很没有头绪的问题,LoadLibrary返回错误号998——“内存分配访问无效”,有的自定义组件无法加载,这次轮到lines和telescope,Windows真是让人郁闷,什么叫“内存分配访问无效”嘛……再详细的信息一点没有,网上也没有相关解答。

只有用排除法,把问题分解成正交的方面,看是那方面出的错了。电脑特性性问题?赶快把开发目录拷到老婆的电脑上,运行,居然没问题!找到不同的实验结果,问题就解决大半了。现在来着重看看,是什么差异导致的不同结果。

说这是每台机器的“个别”问题,那也太玄了吧,仔细一想,还有个不一样的地方——两边的GTK版本不一样,果然,在我机器上用了老版本的GTK之后,组件成功加载了。

说这是GTK版本的问题,那也还是太玄了吧,仔细一想,GTK版本不一样,具体是什么东西不一样呢?导致lines和telescope插件无法加载的改动是,增加了user_object插件,这个插件很普通,但是记得他额外引用了GTK的libglade库,那就在新的GTK下面用老的libglade库,结果问题依旧。突然想起libglade引用了libxml2,再次替换,果然,组件成功加载了!看来就是这个libxml2引起的问题。

说这是libxml2问题,那还是还是也太玄了吧,仔细一想,这两个版本的libxml2有何不同呢?用ProcessExplorer看看,果然,隐约的感觉是对的,他们的Image Base不一样,也就是他们默认加载到进程空间的位置不一样,而新的libxml2加载到了lines和telescope本来应该在的位置!lines和telescope加载的时候,他们默认的Image Base已经被占用,于是有了那个含糊的“内存分配访问无效”!

这就奇怪了,如果加载位置冲突,windows应该会自动的重定位啊,难道只有隐式链接的时候才会重定位?查了一下LoadLibrary,果然是这样。万恶的Windows啊……

那么,解决的办法无非就是吧lines和telescope的Image Base改成其他不冲突的地址,星光飞扬现在使用GNU工具链进行编译,只要在dllwrap.exe的参数中加上“--image-base 0x50100000”就ok了。但是……谁能预料还会有什么dll侵占了新的地址呢?华丽的Windows有着残缺的底层支持。