这个问题搞了我 5 天(包括双休日), 我一定要记录下来。
问题描述
用 Visual Studio 2008 编译 WinCE 7 平台的应用程序,编译没问题,链接时出现了一堆 Link error, 最多的就是 __imp___rt_sdiv
项目结构
在我项目的 sln 文件中有2个projects, 应用程序 a.exe 和 静态链接库 b.lib. 其中 a 用到了 b 中的函数,b.lib 以静态库的方式链接进 a.exe.
Debugging
我当时解决这个问题的思路有 2 种:
1. 参考已有的 WinCE 7 项目 (application + static library) 的项目配置
2. 硬刚这个问题,google "__imp___rt_sdiv"
由于已有现成的WinCE 7 application + static library link 的项目可供参考,于是我先选择了第一种方法。很遗憾,把 C/C++, Linker 中的配置都抄了过来,链接还是相同的错误(后续证明是我抄漏了。。。)。
那就硬刚吧,google "__imp___rt_sdiv" link error, 发现 "__rt_sdiv" 是 ARM compiler's runtime helper function for signed division, 会被 coredll 解析。在我们程序链接时,如果用到函数的在其他 dll 中,编译器会链接时在 Import Address Table(IAT) 表中加上 "__imp_" 前缀,记录地址,以便程序运行时能跳转并找到对应函数。 使用 dumpbin 命令 dump coredll.dll,发现这个符号确实是有的。
导出的 coredll.txt 中有: 2005 6DD 0004BB68 __rt_sdiv
基于上述信息,我猜测可能是 a.exe 链接的时候没有把 WinCE 的系统库 coredll.dll 链接进去,导致找不到 __rt_sdiv. 很有可能是我的 Visual Studio 配置不对。
于是我又回到了方法1,参考已有正常的项目,打开 .vcproj 文件一行一行地去比对。终于找到了几个有问题的配置,修改如下:
1. 同时修改应用程序和库项目的 Properties -> C/C++ -> Code Generation -> Runtime Library -> Multi-threaded DLL (/MD)
- 我之前有问题的配置是 Multi-threaded (/MT)
-
2. 同时修改应用程序和库项目的 Properties -> General -> Code Generation -> Use of MFC -> Use Standard Windows Libraries
-
3. 其他 WinCE 配置参考 - http://www.voidcn.com/article/p-qvbmcyzh-py.html
1. 当前项目右键-属性-平台修改为windows mobile x SDK
2. 配置属性-C/C++-预处理器-预处理器定义栏里面:NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_WINDOWS;_USRDLL;TEST_DLL_EXPORTS;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE
3. 链接器-输入-附加依赖项:strmbase.lib strmiids.lib
4. 链接器-系统-子系统栏-windows CE
___tmainCRTStartup error
这个是另外一个链接问题了,参考 stack overflow 上的答案:
You can do this by adding the following to Properties -> Linker -> Command line:
/ENTRY:"mainCRTStartup"
Reference
https://blogs.msdn.microsoft.com/russellk/2005/03/20/lnk4217/
https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/500949