我們有一些.NET代碼可以調用COM組件(dnsapi.dll)來查詢某個域是否有與其關聯的MX記錄來驗證輸入到我們網站的電子郵件地址。如何更新一些COM編組代碼以在64位系統上工作?
問題是我們已經從32位系統升級到64位系統,並且COM類型和.NET類型之間編組的代碼(並在之後清理)不再正常工作。
COM調用將結果放入內存並返回指向它們的位置的指針。將結果編組爲.NET結構的代碼仍能正常工作,但是在破壞堆並使IIS應用程序池崩潰之後清理內存的代碼仍然正常工作。
這絕對是一個64/32位的問題,因爲我創建了一個調用相同代碼的小控制檯應用程序,並且在我爲32位編譯時工作正常,但在編譯爲64位時顯示相同的堆損壞行爲。
我發現有同樣的問題別人的stackoverflow post,他們說的解決辦法是:
解決的辦法是儘量確保在Win32結構和C#的結構是位(大小)的映射。這可以通過爲win32類型使用精確的c#類型來實現。
我之前沒有做過太多的互操作,也不確定需要改變什麼。下面是MSDN documentation說什麼天然結構是這樣的:
typedef struct _DnsRecord {
DNS_RECORD *pNext;
PWSTR pName;
WORD wType;
WORD wDataLength;
union {
DWORD DW;
DNS_RECORD_FLAGS S;
} Flags;
DWORD dwTtl;
DWORD dwReserved;
union {
DNS_A_DATA A;
DNS_SOA_DATA SOA, Soa;
DNS_PTR_DATA PTR, Ptr, NS, Ns, CNAME, Cname, DNAME, Dname, MB, Mb, MD, Md, MF, Mf, MG, Mg, MR, Mr;
DNS_MINFO_DATA MINFO, Minfo, RP, Rp;
DNS_MX_DATA MX, Mx, AFSDB, Afsdb, RT, Rt;
DNS_TXT_DATA HINFO, Hinfo, ISDN, Isdn, TXT, Txt, X25;
DNS_NULL_DATA Null;
DNS_WKS_DATA WKS, Wks;
DNS_AAAA_DATA AAAA;
DNS_KEY_DATA KEY, Key;
DNS_SIG_DATA SIG, Sig;
DNS_ATMA_DATA ATMA, Atma;
DNS_NXT_DATA NXT, Nxt;
DNS_SRV_DATA SRV, Srv;
DNS_NAPTR_DATA NAPTR, Naptr;
DNS_OPT_DATA OPT, Opt;
DNS_DS_DATA DS, Ds;
DNS_RRSIG_DATA RRSIG, Rrsig;
DNS_NSEC_DATA NSEC, Nsec;
DNS_DNSKEY_DATA DNSKEY, Dnskey;
DNS_TKEY_DATA TKEY, Tkey;
DNS_TSIG_DATA TSIG, Tsig;
DNS_WINS_DATA WINS, Wins;
DNS_WINSR_DATA WINSR, WinsR, NBSTAT, Nbstat;
DNS_DHCID_DATA DHCID;
} Data;
} DNS_RECORD, *PDNS_RECORD;
這裏是我們的.NET結構:
[StructLayout(LayoutKind.Sequential)]
private struct DNSRecord
{
public IntPtr pNext;
public string pName;
public Int16 wType;
public Int16 wDataLength;
public Int32 dwflags;
public Int32 dwTtl;
public Int32 dwReserved;
public IntPtr pNameExchange;
public Int16 wPreference;
public Int16 Pad;
}
我知道IntPtr的是取決於應用程序是否在運行64位或不同的尺寸32位,但似乎並不是我可以專門控制的東西。我不確定我是否需要製作更大或更小的字段。理想情況下,我真的很想了解發生了什麼,以及爲什麼這是一個問題。
我知道另一種選擇是使用純粹通過CLR代碼完成此操作的第三方庫。不幸的是,這是一個.NET1.1庫,現在很難升級,所以我們不能只插入一個.NET庫。我查看了一個可以查詢MX記錄的.NET庫,它們都需要更新版本的.NET。
您應該發佈在本機應用程序中定義的結構。 – tinman