1

プロジェクトに次のマーシャリング コードがあります。これについていくつか質問があります。

[DllImport=(Core.dll, SetLastError=true, EntryPoint="CoreCreate", CharSet="CharSet.Ansi", CallingConvention="CallingConvention.Cdecl")]
internal static extern uint CoreCreate(ref IntPtr core);
  1. なぜ「内部静的外部」が必要なのですか? これは義務ですか?なぜこれが使われるのですか?
  2. SetLastErrorとは?
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
internal struct Channel
{
internal byte LogicalChannel;
}

なぜLayoutKind.Sequential なのか?

4

2 に答える 2

4

なぜ「内部静的外部」が必要なのですか?

internalモディファイアは、メソッドの可視性を設定するだけです。internalメソッドを宣言できるように、privateまたはpublic必要に応じて、他の標準メソッドで行うように、必須である必要はありません。

staticインスタンスメソッドではなく、そのメソッドはクラスを認識しない(ポインタを持たないthis)ため、修飾子が必要です。

最後にextern、メソッドがここではなく別の場所に実装されていることをコンパイラに通知する必要があります(属性を使用する場所を指定します)。Eveyexternメソッドも宣言する必要がありstaticます(オブジェクトに関する知識がない単純な関数呼び出しであるため)。

SetLastErrorとは何ですか?

これは、メソッドがスレッドの最後のエラーコード値を変更する可能性があることを示しています。詳細については、GetLastError()関数を参照してください。呼び出された関数がこの値を変更する場合は、MSDNからに設定SetLastErrorすることをお勧めします。true

ランタイムマーシャラーはGetLastErrorを呼び出し、返された値をキャッシュして、他のAPI呼び出しによって上書きされないようにします。GetLastWin32Errorを呼び出すと、エラーコードを取得できます。

つまり、GetLastError()によって返された値を内部キャッシュに保存するため、システムAPIへの他の呼び出し(他のフレームワーク関数の内部であっても)はその値を上書きしません。

なぜLayoutKind.Sequential?

.NETのクラスレイアウトは、メモリ内でシーケンシャルである必要はありません(シーケンシャル=A前に宣言された場合B、メモリレイアウトはA前にありますB)。これは、宣言の順序が重要なCでは当てはまりません(宣言は、生データのメモリ内のレイアウトを理解するためにコンパイラによって使用されます)。C関数と相互運用する必要がある場合は、それらに渡すデータのレイアウトについて確認する必要があります。これがどのようにLayoutKind.Sequential機能するかです。これは、。内のデータの宣言の順序を尊重するようにコンパイラーに指示しstructます。これは、管理されていない世界と相互運用する唯一のオプションではありません。各フィールドのオフセット(構造体の先頭から)を明示的に設定することもできます(LayoutKind.Explicitを参照)。

于 2012-10-10T09:26:33.870 に答える
1

これは答えではなく、いくつかのコメントです。「内部静的」は1つのことであり、「外部」は外部DLLを呼び出すときに必要な別のものです。SetLastError または GetLastError は、最新の処理に関するウィンドウからエラー メッセージを取得するために「昔」によく使用されたメソッドです。LayoutKind.Sequential は、指定された方法で構造体をレイアウトするようにコンパイラに通知する方法です。他のシステムにマーチャリングする場合は、これを行う必要がある場合があります。

于 2012-10-10T09:25:26.743 に答える