ホームページ >バックエンド開発 >PHPチュートリアル >Windows を呼び出す C# の重要なポイント api_PHP チュートリアル
.Net Framework SDK ドキュメントでは、Windows API を呼び出すための手順が比較的分散されており、より包括的なものは Visual Basic .net 用です。この記事では、C# で API を呼び出す際の重要なポイントを次のようにまとめています。C# で API を使用したことがない友人の参考になれば幸いです。さらに、Visual Studio .net がインストールされている場合は、C:/Program Files/Microsoft Visual Studio .NET/FrameworkSDK/Samples/Technologies/Interop/PlatformInvoke/WinAPIs/CS ディレクトリに API 呼び出しの例が多数あります。
1.通話形式
using System.Runtime.InteropServices; //次のコードを簡略化するためにこの名前空間を参照します
…
//DllImportAttribute 機能を使用して API 関数を導入します。空のメソッドが宣言されている、つまりメソッド本体が空であることに注意してください。
[DllImport("user32.dll")]
public static extern ReturnType FunctionName(type arg1,type arg2,...);
//他のメソッドの呼び出しと呼び出しに違いはありません
DllImportAttribute 属性のパブリック フィールドは次のとおりです。
1. CallingConvention は、アンマネージ実装にメソッドのパラメーターを渡すときに使用される CallingConvention の値を示します。CallingConvention.Cdecl: 呼び出し元はスタックをクリアします。これにより、可変引数を使用して関数を呼び出すことができます。
CallingConvention.StdCall: 呼び出し先はスタックをクリアします。これは、マネージ コードからアンマネージ関数を呼び出すための既定の規則です。
2. CharSet は、呼び出し元の関数の名前のバージョンを制御し、String パラメーターをメソッドにマーシャリングする方法を示します。
このフィールドは、CharSet 値のいずれかに設定されます。 CharSet フィールドが Unicode に設定されている場合、すべての文字列パラメータはアンマネージ実装に渡される前に Unicode 文字に変換されます。これにより、DLL EntryPoint の名前に文字「W」が追加されます。このフィールドが Ansi に設定されている場合、文字列は ANSI 文字列に変換され、DLL EntryPoint の名前に文字「A」が追加されます。ほとんどの Win32 API は、「W」または「A」を追加するこの規則を使用します。 CharSet が Auto に設定されている場合、この変換はプラットフォームに依存します (Windows NT では Unicode、Windows 98 では Ansi)。 CharSet のデフォルト値は Ansi です。 CharSet フィールドは、指定された DLL からインポートされる関数のバージョンを決定するためにも使用されます。 CharSet.Ansi と CharSet.Unicode の名前一致ルールはまったく異なります。 Ansi の場合、EntryPoint が「MyMethod」に設定されており、それが存在する場合、「MyMethod」が返されます。 DLL に「MyMethod」が存在せず、「MyMethodA」が存在する場合は、「MyMethodA」が返されます。 Unicode の場合はその逆です。 EntryPoint が "MyMethod" に設定されており、それが存在する場合は、"MyMethodW" を返します。 「MyMethodW」が DLL に存在しないが、「MyMethod」は存在する場合は、「MyMethod」が返されます。 Auto を使用している場合、一致ルールはプラットフォームに依存します (Windows NT では Unicode、Windows 98 では Ansi)。 ExactSpelling が true に設定されている場合、DLL に「MyMethod」が存在する場合にのみ「MyMethod」が返されます。
3. EntryPointは、呼び出されるDLLエントリポイントの名前またはシリアル番号を示します。
メソッド名を API 関数と同じにしたくない場合は、次のようにこのパラメーターを指定する必要があります:
[DllImport("user32.dll",CharSet="CharSet.Auto",EntryPoint="MessageBox")]
public static extern int MsgBox(IntPtr hWnd,string txt,string caption, int type);
4. ExactSpelling は、アンマネージ DLL 内のエントリ ポイントの名前を、CharSet フィールドで指定された CharSet 値に対応するように変更する必要があるかどうかを示します。 true の場合、DllImportAttribute.CharSet フィールドが CharSet の Ansi 値に設定されている場合はメソッド名に文字 A が追加され、DllImportAttribute.CharSet フィールドが Unicode 値に設定されている場合はメソッド名に文字 W が追加されます。文字コード。このフィールドのデフォルト値は false です。
5. PreserveSig は、マネージド メソッドのシグネチャが HRESULT を返すように変換されるべきではなく、戻り値に対応する追加の [out, retval] パラメーターを持つアンマネージド シグネチャを持つ可能性があることを示します。
6. SetLastError は、呼び出し先が属性付きメソッドから戻る前に Win32 API SetLastError を呼び出すことを示します。 true は、呼び出し元が SetLastError を呼び出すことを示します。デフォルトは false です。ランタイム マーシャラーは GetLastError を呼び出し、返された値をキャッシュして、他の API 呼び出しによって上書きされないようにします。ユーザーは、GetLastWin32Error を呼び出すことでエラー コードを取得できます。
2.パラメータの種類:
1. 数値型の場合は、対応するものを使用してください。
2. 文字列ポインタ(api) -> 文字列(.net)
3. ハンドル(dWord) -> IntPtr
4. 構造 -> 構造またはクラス
この場合、まず StructLayout 属性を使用してステートメントを修飾する必要があります。例:
// クラスとして宣言
[ StructLayout( LayoutKind.Sequential )]
パブリッククラスOSVersionInfo
{
public int OSVersionInfoSize;
public int MajorVersion;
public intminorVersion;
public int buildNumber;
public int platformId;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
public String versionString;
}
// structとして宣言
[ StructLayout( LayoutKind.Sequential )]
パブリック構造体 OSVersionInfo2
{
public int OSVersionInfoSize;
public int MajorVersion;
public intminorVersion;
public int buildNumber;
public int platformId;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
public String versionString;
}
MashalAs 機能: フィールド、メソッド、またはパラメーターのマーシャリング形式を記述するために使用されます。属性はパラメータに接頭辞を付け、ターゲットに必要なデータ型を指定します。たとえば、次のコードは、2 つのパラメーターを Windows API 関数 String (LPStr) にデータ型 Long ポインターとしてマーシャリングします。
[MarshalAs(UnmanagedType.LPStr)]文字列既存ファイル;
[MarshalAs(UnmanagedType.LPStr)]
文字列 newfile;
構造体をパラメータとして使用する場合、ref 修飾子を前に追加する必要があることに注意してください。そうしないと、オブジェクトへの参照がオブジェクトのインスタンスを指定していませんというエラーが発生します。
[DllImport( "kernel32", EntryPoint="GetVersionEx" )]
public static extern bool GetVersionEx2( ref OSVersionInfo2 osvi );
3. プラットフォーム呼び出しを呼び出した後、管理対象オブジェクトがどこにも参照されていない場合、ガベージ コレクターは管理対象オブジェクトを完了する可能性があります。これによりリソースが解放され、ハンドルが無効になり、プラットフォーム呼び出し呼び出しが失敗します。 HandleRef でハンドルをラップすると、プラットフォーム呼び出し呼び出しが完了するまで管理オブジェクトがガベージ コレクションされなくなります。