Windows API(データ型を含む)をP/Invokeに変換する場合、DWORDをint
またはuint
に置き換える必要がありますか?
通常は署名されていませんが、代わりにあらゆる場所でint
を使用している人がいます(CLSの警告だけですか? 。NET Framework自体でも は this です) 、だから、どれが正しいものなのか本当によくわかりません。
さて MSDNによるとDWORD
は、0〜4294967295の範囲の符号なし整数です。
理想的には、uint
ではなくint
に置き換える必要があります。
ただし、uint
はCLSに準拠していないため、メソッドが公開されている場合はint
を使用して変換を行う必要があります。その結果、メソッドがアセンブリの外部で使用されていない場合、internal
ではなくpublic
としてマークする必要があります。その後、uint
を使用できるようになります。
Intを使用します。 "AutoRestartShell"をint変数で変更した場合の理由:
regKey.SetValue("AutoRestartShell", uintVariable);
レジストリエディターのデータ型が"REG_SZ"に変更されます。その値が返されるように要求する場合:
regKey.GetValue("AutoRestartShell");
stringが返されます。
ただし、"AutoRestartShell"をint変数で変更した場合:
regKey.SetValue("AutoRestartShell", intVariable);
データ型は"REG_DWORD"のままです。
なぜこれが起こるのですか?わからない。私が知っているのは、それがするということです。ロジックは、確かにuintを使用する必要があることを教えてくれますが、それは望まないデータ型を変更します。
署名されていないため、uint
にマップします。
DWORDは、(Microsoftの)定義によると、符号なし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
CLS準拠の警告は、アセンブリの外部でP/Invokeメソッドが表示されている場合にのみ適用されます。これは一般に、呼び出しがパブリックであることを意味します。メソッドが外部から見えない場合は、uint
を使用してもかまいません。
悲しいことに、Read Registryはintを使用する必要があります。そうでなければ、例外をスローします。このMicrosoftコード:
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ですが