P/Invokingの前に機能が存在するかどうかを検出するための良い方法を見つけようとしています。C/.NETでのP /呼び出し時の機能検出
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
がこの機能を持っていないいくつかのシステムでクラッシュします。たとえば、ネイティブStrCmpLogicalW
関数を呼び出します。
i don't want to perform version checkingこれは悪い習慣であり、間違っていることもあります(たとえば、機能がバックポートされているか、機能をアンインストールできる場合など)。
正しい方法は、shlwapi.dll
から輸出の存在をチェックすることです:
private static _StrCmpLogicalW: function(String psz1, String psz2): Integer;
private Boolean _StrCmpLogicalWInitialized;
public int StrCmpLogicalW(String psz1, psz2)
{
if (!_StrCmpLogialInitialized)
{
_StrCmpLogicalW = GetProcedure("shlwapi.dll", "StrCmpLogicalW");
_StrCmpLogicalWInitialized = true;
}
if (_StrCmpLogicalW)
return _StrCmpLogicalW(psz1, psz2)
else
return String.Compare(psz1, psz2, StringComparison.CurrentCultureIgnoreCase);
}
問題は、もちろん、すなわち、C#は関数ポインタをサポートしていないということです。
_StrCmpLogicalW = GetProcedure("shlwapi.dll", "StrCmpLogicalW");
はできません。
私は.NETで同じロジックを実行するための代替構文を見つけようとしています。私はこれまでのところ以下の擬似コードを持っていますが、私は窮地に瀕しています:
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
private Boolean IsSupported = false;
private Boolean IsInitialized = false;
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, Export="StrCmpLogicalW", CaseSensitivie=false, SetsLastError=true, IsNative=false, SupportsPeanutMandMs=true)]
private static extern int UnsafeStrCmpLogicalW(string psz1, string psz2);
public int StrCmpLogicalW(string s1, string s2)
{
if (!IsInitialized)
{
//todo: figure out how to loadLibrary in .net
//todo: figure out how to getProcedureAddress in .net
IsSupported = (result from getProcedureAddress is not null);
IsInitialized = true;
}
if (IsSupported)
return UnsafeStrCmpLogicalW(s1, s2);
else
return String.Compare(s1, s2, StringComparison.CurrentCultureIgnoreCase);
}
}
私はいくつかの助けが必要です。
私はの存在を検出したいいくつかの輸出の別の例は次のようになります。
dwmapi.dll::DwmIsCompositionEnabled
dwmapi.dll::DwmExtendFrameIntoClientArea
dwmapi.dll::DwmGetColorizationColor
dwmapi.dll::DwmGetColorizationParameters
(文書化されていない、まだエクスポートされません氏名、序数127) Windows 7のSP1
dwmapi.dll::127
(文書化されていない、DwmGetColorizationParameters)
のよう
すでにOSの機能の有無をチェックするための.NETのデザインパターンが存在する必要があります。誰でも、.NETでの機能検出を行うために推奨される方法の例を教えていただけますか?
.NET Frameworkのソースコードのデザインパターンは、OSのバージョン番号を確認することですが、Larry Osterman氏がブログ記事で結論づけるように、*インテリジェントに*行うことです。私はJohannのソリューションがおそらくより優れていることに同意しますが、私もWin32の人です。 'LoadLibrary'と' GetProcAddress'はちょうど*私に意味があります*。私は.NETコードを書くときにP/Invokeの定義を書いている時間のほとんどを費やします。それが本当に良いのかどうかはわかりません。 –
@Cody:*実際には良いのかどうかは分かりません。*おそらくそうではありません。 :-) –
@ CodeGrayバージョン番号は信頼できません。機能が遡及的にOSに移植されている可能性があります(バージョン番号が間違っている)。また、機能がユーザーによってインストールされない可能性もあります(バージョン番号が間違っている)。 –