LoadLibrary 无法加载 DLL 的 bug 处理

云风 2018-03-15 10:40

今天我们的小伙伴在把 Open Asset Import Library 封装成 lua 库的时候遇到一些麻烦。他在 vs 集成环境中编译的版本可以用,在 mingw-gcc 下却出错,报告 “找不到指定的模块。” 或是 “找不到指定的程序。" 。

我不得不吐槽,微软真是太有钱了,雇了一大帮人把出错信息都给国际化,这叫中国程序员怎么 google 问题啊。不太懂 windows ,反正我用 export LANG= 切换了 locale 为 C 还是不能把这段用 FormatMessage 格式化出来的 GetLastError 获得的出错码的错误串变成英文。还请读者中的 windows 大牛在留言中赐教。写这篇 blog 的主要目的就是以后有人可以用上面的出错信息关键词 google 过来。让我们一起来吐槽微软。

不过经验告诉我,不管是模块找不到还是什么程序找不到,这是 DLL 依赖问题。DLL 缺失这种问题,Dependency Walker可以查。这个工具最早在 VC 里就自带,现在也能找到单独下载。不过安装了 mingw/msys 的话,我更喜欢用 ldd 。是的,linux 下的神器 ldd 现在有 windows 版了。

我前段发的 iup 的项目 iupmingw 就有同学碰到过类似的问题:https://github.com/cloudwu/iupmingw/issues/1

不过这次并不是缺少 dll ,为了观察 windows 的加载 dll 过程,它居然不报告到底在哪个环节出错,找不到 dll 也不报告文件名,我动用了另一个神器ProcessMonitor,推荐给大家使用。它可以监控进程的系统调用,比如加载动态库呀,打开文件啊,打开注册表啊。有了这个,windows 下写程序就不再是两眼一抹黑了。什么文件删不掉,看看谁锁住了它,用这个都能查到。可是为啥 windows 会有那么多文件锁住不准删这种事呢?

回头来看看 "找不到指定的模块。" 这条信息吧,它的 Error Code 是 126 ,英文是 The specified module could not be found 。用直白的话讲就是某个依赖的 dll 找不到。

"找不到指定的程序。" 这条信息的 Error Code 是 127 ,英文是 The specified procedure could not be found 。用直白的话讲是 dll 都找到了,但是 dll 里需要的符号找不到,通常就是版本有问题。

本文最初的问题应该是在构建的时候混用了 mingw gcc c++ 的 sjlj 和 seh 的异常处理 dll 导致的。这就是另一个话题了。

[返回] [原文链接]