將Windows API(包括數據類型)翻譯成P/Invoke時,我應該用int
還是uint
替換DWORD?應該將DWORD映射爲int還是uint?
它通常無符號的,但我看到使用int
世界各地的人們,而不是(它只是因爲CLS警告?even the .NET Framework itself確實this),所以我從來沒有真正知道哪一個是正確的使用。
將Windows API(包括數據類型)翻譯成P/Invoke時,我應該用int
還是uint
替換DWORD?應該將DWORD映射爲int還是uint?
它通常無符號的,但我看到使用int
世界各地的人們,而不是(它只是因爲CLS警告?even the .NET Framework itself確實this),所以我從來沒有真正知道哪一個是正確的使用。
好according to the MSDNDWORD
是範圍爲0的無符號整數到4294967295
所以最好你應該uint
而不是int
更換。
但是,因爲您發現uint
不符合CLS,所以如果您的方法是公開可見的,則應使用int
並進行轉換。這是因爲如果你的方法不是在你的程序集外部使用,你應該將它標記爲internal
而不是public
。那麼你就可以使用uint
。
它未簽名,因此將其映射到uint
。
根據(Microsoft's)的定義,DWORD是一個無符號的32位整數。它應該映射到您的編譯器用來表示該類型的任何類型。
現在很可能是一個unsigned int,但這不是一個可移植的實現。我知道你正在使用C#,而是讓你我更熟悉的語言的例子,在C典型的實現可能是:
#if defined(SOME_HARDWARE_IMPLEMENTATION)
#define DWORD unsigned int
#elif #defined(SOME_OTHER_IMPLEMENTATION)
#define DWORD unsigned long
#elif #defined(YET_ANOTHER_IMPLEMENTATION)
#define DWORD something_else
#else
#error Unsupported hardware; cannot map DWORD
#endif
但是,在C#中,'uint'和'int'是32位整數。不過,你是正確的,在C語言中,像'int'和'long'這樣的原始數據類型在編譯器之間並不一致。但是,如果在未由Microsoft定義的函數或API中使用DWORD,DWORD是一個32位無符號整數,但這只是一個問題。 –
C int和long在窗口上始終爲32位 –
的CLS遵從性警告只適用於在P/Invoke的方法在程序集外部可見,這通常意味着該調用是公開的。如果該方法不是外部可見的,則可以使用uint
。
使用int。原因是,如果我改變「AutoRestartShell」與UINT變量:
regKey.SetValue("AutoRestartShell", uintVariable);
在註冊表編輯器變爲「REG_SZ」的數據類型。
regKey.GetValue("AutoRestartShell");
一個串獲取返回:如果我要的是價值與返回。
然而,如果我改變「AutoRestartShell」與INT變量:
regKey.SetValue("AutoRestartShell", intVariable);
數據類型保持原樣「REG_DWORD」。
爲什麼會發生這種情況?不知道。我所知道的是它的確如此。邏輯肯定會告訴我們應該使用uint,但這會改變我們不想要的數據類型。
.NET的行爲或完全不相關的部分如何與編組WinApi類型相關? – IllidanS4
出於同樣的原因,兩個應用程序無法通過一個發送整數相互通信,而另一個需要字符串,反之亦然。至於uint或int是否會在這裏產生實際的差異,我不知道。這只是一個觀察。我認爲最好不要改變什麼不需要改變。 – Rehaan
它看起來像罪魁禍首是私人* CalculateValueKind *方法。它根本不承認'uint',但也不知道'short'或其他數字類型。但我明白了 - 公共API應該比非CLS兼容類型更重要地處理CLS兼容類型。 CLR實際上並不區分'int'和'uint'。 – IllidanS4
可悲的是,閱讀註冊必須使用int否則拋出exception.this微軟代碼:
private static void Get45or451FromRegistry()
{
using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\")) {
if (ndpKey != null && ndpKey.GetValue("Release") != null) {
Console.WriteLine("Version: " + CheckFor45DotVersion((int) ndpKey.GetValue("Release")));
}
else {
Console.WriteLine("Version 4.5 or later is not detected.");
}
}
}
雖然釋放REG_DWORD
我猜我擔心的是,它是(1)與框架不一致, (2)不符合CLS。我應該忽略它嗎? – Mehrdad