在VB6中,我打電話給Windows API DnsQuery。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。我認爲其他(35)提供了一個足夠大的容器,當返回的實際結構比預期的要大時(那裏有一些變長的類型UNIONed)。有關更多詳細信息,請參閱DNS_RECORD structure。
所以,我有2個問題:在VB
字符串是真的,在幕後,雙字指針(4個字節,又名一個Long)。有一點我認爲我可以將Name聲明爲String,因爲這隻需將指針放在那裏並正確工作(就像將VB字符串傳遞給API調用時一樣)。但是,我猜應用程序終止是因爲它是一個C風格的字符串而不是VB風格的字符串,並且VB在字符串開始之前查找長度值的內存位置,並獲取一些隨機數垃圾和炸燬。這是一個合理的猜測嗎?
當我使用返回DNS RR類型的DNS_PTR_DATA或DNS_A_DATA時,我對DnsQuery的調用起作用,但是當我嘗試DNS_TXT_DATA時,它已經炸燬了。其他人可以發現我做錯了什麼嗎?查看案例DNS_TYPE_TEXT,並在下面查看我的評論。現在
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結構的指針,我得到了字符串的數量。當我通過其他(3)檢查其他(0)時,它們都具有使我懷疑接下來的四個字節是指針的值。那麼是什麼給了?爲什麼這個結構只是以「內聯」方式進入,而其他結構是作爲指向結構開始的指針?
我很感激任何幫助!
1)VB字符串是否也以空字符結尾?所以VB字符串工作正常,因爲C字符串,但不是相反的方式,對嗎? 2)現在我終於明白了!我被inet_ntoa調用拋出,它返回一個(指向一個)字符串的指針。但它確實只是一種價值。不知何故,我得到它是一個指針。我現在確切地知道該怎麼做(但直到星期二才能回覆它)。 – ErikE 2010-02-14 23:58:12
我不認爲VB字符串是nul-terminated;另外,他們使用廣泛的字符。您應該在兩個方向上使用轉換例程。 – jdigital 2010-02-16 19:16:11
如果他們使用寬字符和API函數不,那麼CopyMemory將無法正常工作,但它確實有效。看來你在理論上比實際回答更多? – ErikE 2010-02-17 00:35:16