【发布时间】:2010-02-13 03:03:41
【问题描述】:
在 VB6 中,我正在调用 Windows API DnsQuery。
Private Declare Function DnsQuery Lib "dnsapi" Alias "DnsQuery_A" ( _
ByVal lpstrName As String, _
ByVal wType As Integer, _
ByVal Options As Long, _
ByVal pServers As Long, _
ppQueryResultsSet As Long, _
ByVal pReserved As Long) As Long
Private Type VBDnsRecord
pNext As Long
pName As Long
'Name As String ' Commented out, see question
wType As Integer
wDataLength As Integer
Flags As Long
dwTtl As Long
dwReserved As Long
ptrData As Long
Others(35) As Byte
End Type
我的结构声明来自here。我假设 Others(35) 是在返回的实际结构大于预期时提供足够大的容器(其中有一些可变长度类型 UNIONed)。有关详细信息,请参阅DNS_RECORD structure。
所以,我有两个问题:
VB 中的字符串在幕后实际上是双字指针(4 个字节,又名 Long)。有一段时间,我想我可以将 Name 声明为 String,因为这只会将指针放在那里并正常工作(就像将 VB 字符串传递给 API 调用时一样)。但是,我猜我得到的应用程序终止是因为它是 C 风格的字符串而不是 VB 风格的字符串,并且 VB 在字符串开始之前的内存位置中查找长度值,并得到一些随机垃圾和爆炸。这是一个合理的猜测吗?
-
当我使用返回 DNS_PTR_DATA 或 DNS_A_DATA 的 DNS RR 类型时,我对 DnsQuery 的调用有效,但是当我尝试使用 DNS_TXT_DATA 时,它会爆炸。其他人可以发现我做错了什么吗?查看 Case DNS_TYPE_TEXT,并在下面查看我的 cmets。
RetVal = DnsQuery(DnsName, QueryType, DNS_QUERY_BYPASS_CACHE, pServers, pDnsRecord, 0) If RetVal = 0 Then pNext = pDnsRecord Do While pNext <> 0 CopyMemory DnsRecord, pNext, Len(DnsRecord) Select Case DnsRecord.wType Case DNS_TYPE_A Ptr = inet_ntoa(DnsRecord.ptrData) TempString = String(lstrlen(Ptr), 0) CopyMemory ByVal TempString, Ptr, Len(TempString) Case DNS_TYPE_PTR, DNS_TYPE_NS, DNS_TYPE_CNAME, DNS_TYPE_DNAME, DNS_TYPE_MB, DNS_TYPE_MD, DNS_TYPE_MF, DNS_TYPE_MG, DNS_TYPE_MR Ptr = DnsRecord.ptrData TempString = String$(lstrlen(Ptr), 0) CopyMemory ByVal TempString, Ptr, Len(TempString) Case DNS_TYPE_TEXT, DNS_TYPE_HINFO, DNS_TYPE_ISDN, DNS_TYPE_TEXT, DNS_TYPE_X25 Dim TextData As Dns_Txt_Data Ptr = DnsRecord.ptrData CopyMemory VarPtr(TextData), Ptr, Len(TextData) Stop Case Else TempString = "unhandled resource record type" End Select If Not FullRecord Then DnsLookup = " " & TempString Exit Do Else DnsLookup = DnsLookup & " " & vbCrLf & DnsTypeNameFromCode(DnsRecord.wType) & " " & TempString End If pNext = DnsRecord.pNext Loop现在,当我在 CopyMemory 行设置断点并检查 Ptr 的值时,我预计会有数百万或更高的值,表明它是一个指针,但我得到的值是 1(这解释了为什么所有当我尝试从该内存位置复制时爆炸)。这似乎向我表明,我得到的不是指向预期的 DNS_TXT_DATA 结构的指针,而是字符串的计数。当我检查 Other(0) 到 Other(3) 时,它们都具有使我怀疑接下来的四个字节是指针的值。那么给了什么?为什么这个结构只是“内联”进来,而其他的则作为指向结构开始的指针进来?
感谢您的帮助!
【问题讨论】: