MinGW 64位环境下使用--wrap重写time函数失效的求助
解决MinGW 11.2.0(64位)下
time函数wrap失效问题 问题背景
为满足测试自动化需求,需重写代码中多处调用的time函数。此前使用MinGW 7.3.0(32位)时,通过链接器标志-Wl,--wrap=time将系统time函数调用重定向到自定义模块,同时为Windows环境包装_time32(因MinGW会将time内联转发到_time32),方案运行正常。但切换到MinGW 11.2.0(64位)后,重写功能失效:
- 尝试包装
_time64替代_time32未成功 - 手动添加
extern "C" time_t time(time_t *);声明后重写可正常工作,但违背了用wrap避免修改全量源码的初衷
环境与代码信息
当前链接脚本(qmake.pro)
TARGET = Sandbox TEMPLATE = app CONFIG *= console CONFIG -= qt app_bundle SOURCES += main.cpp \ #MainWindow.cpp SecondFile.c QMAKE_CFLAGS += -fsigned-char QMAKE_CXXFLAGS += -fsigned-char QMAKE_LFLAGS += -Wl,--wrap=__time64 -Wl,--wrap=time
main.cpp代码
#include <stdio.h> #include <time.h> // extern "C" { // time_t time(time_t *); // } int main(int, char **) { time_t timestamp; time(×tamp); printf("%lu\n", timestamp); return 0; }
SecondFile.c代码
#include <stdio.h> time_t __wrap_time(time_t *p) { if (p) *p = 1; return 1; } time_t __wrap__time32(time_t *p) { return __wrap_time(p); } time_t __wrap__time64(time_t *p) { return __wrap_time(p); }
nm命令输出的.o文件关键信息
U __imp___acrt_iob_func U __imp__time64 U __main U __mingw_vfprintf 000000000000001f T main 0000000000000000 t time
问题分析
MinGW 11.2.0的time.h中,time函数被定义为static __inline,编译时会直接内联展开为对_time64的导入调用(即__imp__time64)。链接器的--wrap默认仅处理普通的未定义符号,无法直接替换导入表中的__imp__前缀符号;若强行包装__imp__time64,会导致程序运行时段错误。
无需修改源码的解决方案
方案1:禁用inline版本的time函数
通过编译宏强制MinGW使用外部链接的time函数,而非内联版本。修改qmake的编译选项:
QMAKE_CFLAGS += -fsigned-char -D__NO_INLINE__ QMAKE_CXXFLAGS += -fsigned-char -D__NO_INLINE__ QMAKE_LFLAGS += -Wl,--wrap=time
__NO_INLINE__宏会让MinGW的头文件不使用inline版本的标准库函数,转而生成对外部time函数的调用- 此时链接器的
--wrap=time就能正常将time调用重定向到__wrap_time,无需修改业务源码
方案2:针对导入符号的wrap技巧(进阶)
若不想禁用所有inline函数,可通过链接器的特殊处理wrap_time64的导入符号:
- 修改链接器标志:
QMAKE_LFLAGS += -Wl,--wrap=_time64
- 确保SecondFile.c中的
__wrap__time64函数签名与系统_time64完全匹配:
__time64_t __wrap__time64(__time64_t *p) { if (p) *p = 1; return 1; }
- 该方案利用链接器对导入符号的wrap支持,但需注意不同MinGW版本的兼容性,推荐优先使用方案1
内容的提问来源于stack exchange,提问作者Refugnic Eternium
相关产品推荐
相关产品推荐

