MinGW编译C程序遇RegGetValue未声明及链接错误求助
问题:MinGW编译调用RegGetValue时的隐式声明与链接错误
环境与代码
Windows 7 64位系统,使用MinGW 9.2.0编译C程序,代码如下:
#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <inttypes.h> void readRegDwordValue() { HKEY hKey = HKEY_LOCAL_MACHINE; char const *subKey = "Software\\Metpl\\My Program"; char const *pValue = "MJP_XXX"; uint32_t flags = RRF_RT_REG_DWORD; int *pvData = NULL; int64_t result = RegGetValue(hKey, &subKey, pValue, flags, NULL, pvData, sizeof(DWORD)); if (result != ERROR_SUCCESS) { printf("Error getting value. Code: "); printf("%" PRId64 "\n", result); } else { printf("Value data: "); printf("%" PRId32 "\n", *(int32_t*)pvData); } } int main() { readRegDwordValue(); return 0; }
编译警告
执行编译命令:
gcc -O3 -Wall -c -o readReg.o readReg.c
得到警告:
readReg.c: In function 'readRegDwordValue': readReg.c:13:22: warning: implicit declaration of function 'RegGetValue'; did you mean 'RegSetValue'? [-Wimplicit-function-declaration] 13 | int64_t result = RegGetValue(hKey, &subKey, pValue, flags, NULL, pvData, sizeof(DWORD)); | ^~~~~~~~~~~ | RegSetValue
链接错误
执行链接命令:
gcc readReg.o -o readReg.exe -L -liphlpapi -ladvapi32
得到错误:
d:/__sdk/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: readReg.o:readReg.c:(.text+0x45): undefined reference to `RegGetValue' collect2.exe: error: ld returned 1 exit status
解决思路
- 指定API最低版本宏:
RegGetValue是Windows Vista及以后引入的API,MinGW的头文件默认不会开启该函数的声明。需要在包含windows.h前定义_WIN32_WINNT宏为0x0600(对应Vista版本)或更高,让编译器识别到函数声明:#define _WIN32_WINNT 0x0600 #include <windows.h> - 显式调用ANSI版本函数:MinGW中
RegGetValue是宏,会根据字符集定义转成RegGetValueA或RegGetValueW。因为代码里用的是char*类型的字符串,直接调用RegGetValueA可避免宏定义问题,同时修正参数错误:- 原代码中
&subKey是char const**类型,函数需要的是LPCSTR(即char const*),直接传subKey即可 pvData不能为NULL,需定义DWORD类型变量作为缓冲区,并传入其地址和大小
修正后的调用代码:
注意:DWORD pvData = 0; DWORD dataSize = sizeof(DWORD); LONG result = RegGetValueA(hKey, subKey, pValue, flags, NULL, &pvData, &dataSize);RegGetValue返回值类型是LONG,不是int64_t,需修正类型匹配。 - 原代码中
- 调整链接命令:确保
-ladvapi32放在编译命令末尾(链接器按顺序处理库,依赖库要放在目标文件之后),同时去掉无用的-L(无指定路径时无需添加),命令改为:gcc -O3 -Wall -c -o readReg.o readReg.c gcc readReg.o -o readReg.exe -liphlpapi -ladvapi32
内容的提问来源于stack exchange,提问作者Manish
相关产品推荐
相关产品推荐

