如何用WinAPI查询多行DNS TXT记录?解析MIDL_PASS宏含义
问题解答
1. MIDL_PASS宏的含义
MIDL_PASS是微软MIDL(Interface Definition Language)编译器专属的宏,用于区分MIDL编译流程和C/C++编译流程:
- 当MIDL编译器处理头文件时,会自动定义该宏,此时结构体中的
[size_is(dwStringCount)]是MIDL的属性注解,用于告知编译器pStringArray的动态数组长度由dwStringCount字段决定——这是RPC/COM场景中描述可变长度数组的标准写法。 - 当C/C++编译器编译代码时,该宏未定义,结构体退化为
pStringArray[1]的形式,这是C语言中模拟柔性数组的经典实现:用大小为1的数组占位,实际内存分配时会根据真实数据长度扩展空间。
2. 启用MIDL_PASS后编译错误的解决
手动定义MIDL_PASS会导致C/C编译器无法识别MIDL专属的属性注解(如[size_is]),这些语法仅被MIDL编译器支持,C/C编译器完全不认识,因此会报“identifier not found”“attribute not found”类错误。
解决方式:不要手动定义MIDL_PASS宏。该宏仅用于MIDL编译阶段,C/C++编译时保持默认未定义状态即可。若要访问柔性数组的后续元素,可将pStringArray强制转换为指针类型:
// 将柔性数组转为指针,访问所有元素 PWSTR* txtStringPtr = reinterpret_cast<PWSTR*>(dnsRecord->Data.TXT.pStringArray); for (size_t i = 0; i < dnsRecord->Data.TXT.dwStringCount; ++i) { wcout << i << L": " << txtStringPtr[i] << endl; }
3. 关于dwStringCount始终为1的问题
你遇到的dwStringCount始终为1的情况,可能由以下原因导致:
- 目标域名的TXT记录本身仅配置了一条,或DNS服务商将多条TXT记录合并为单条返回。
- 若确认域名存在多条TXT记录,可尝试调整
DnsQuery的参数(如移除DNS_QUERY_BYPASS_CACHE),或改用更现代的DnsQueryExAPI进行测试:
DNS_QUERY_REQUEST request = {0}; request.Version = DNS_QUERY_REQUEST_VERSION1; request.QueryName = domain.data(); request.QueryType = DNS_TYPE_TEXT; request.Options = DNS_QUERY_BYPASS_CACHE; request.pDnsServerList = &dnsServerIp; DNS_QUERY_RESULT result = {0}; auto error = DnsQueryEx(&request, &result); if (!error) { if (result.pQueryRecords) { DNS_RECORD* record = result.pQueryRecords; // 遍历所有返回的DNS记录 while (record) { if (record->wType == DNS_TYPE_TEXT) { cout << "DNS TXT strings count: " << record->Data.TXT.dwStringCount << endl; PWSTR* txtStringPtr = reinterpret_cast<PWSTR*>(record->Data.TXT.pStringArray); for (size_t i = 0; i < record->Data.TXT.dwStringCount; ++i) { wcout << i << L": " << txtStringPtr[i] << endl; } } record = record->pNext; } DnsRecordListFree(result.pQueryRecords, DnsFreeRecordListDeep); } }
内容的提问来源于stack exchange,提问作者qloq
相关产品推荐
相关产品推荐

