VB.NET での DllImport と宣言
質問
MSDN ドキュメントに次のような記載があることに気付きました。 複数の方法 VB.NET プログラム内から外部 DLL 内の関数への参照を宣言します。
混乱を招くのは、MSDN が、 DllImport属性 共有関数プロトタイプを含むクラス "まれに" とありますが、このステートメントの説明は見つかりませんでした。一方、単に Declare
代わりにキーワード。
これらはなぜ異なるのでしょうか?それぞれのケースをどこで適切に使用すればよいでしょうか?
解決
宣言本当に P /により熟知しているであろうの構文を起動します VB.NETするに変換するVisual Basic 6.0のユーザー。これは、P /呼び出しが、特定の種類のマーシャリングと同じ機能の多くを持って、特定の文字列では、非常に異なっており、DLLIMPORTルールに慣れて人々に混乱のビットを引き起こす可能性があります。
私は、ドキュメントが「珍しい」の区別とをほのめかしているものを完全にはよく分かりません。私は問題のないVB.NETとC#の両方から頻繁に私のコードでDLLIMPORTを使用します。
一般的に、私は、Visual Basic 6.0の背景から来ていない限りオーバー宣言DLLIMPORTを使用します。 DLLIMPORTのドキュメントとサンプルが非常に優れているとの宣言をDLLIMPORT生成を目的とした多くのツールがあります。
他のヒント
どうやら、Declare ステートメントと DllImport ステートメントは基本的に同じです。どちらでもお好みでご使用いただけます。
以下に、それぞれの動作が少し異なる可能性があるいくつかの点について説明します。これらの点は、どちらかの優先順位に影響を与える可能性があります。
まず、MSDN の Visual Studio 2003 に関する記事というタイトルの記事から始めました。 DllImport 属性の使用. 。(少し古いですが、DllImport ステートメントは .NET で生まれたと思われるため、最初に戻るのが適切であると考えられました。)
次の DllImport ステートメントの例を考えます。
[DllImport("user32.dll", EntryPoint = "MessageBox", CharSet = Unicode)]
int MessageBox(void* hWnd, wchar_t* lpText, wchar_t* lpCaption, unsigned int uType);
EntryPoint 値が省略された場合、 CLR デフォルトとして関数の名前 (この場合は MessageBox) が検索されます。ただし、この例では Unicode の CharSet が指定されているため、CLR は最初に「MessageBoxW」と呼ばれる関数を探します。「W」は Unicode 戻り値の型を示します。(ANSI 戻り値の型のバージョンは「MessageBoxA」になります。)「MessageBoxW」が見つからなかった場合、CLR は実際に「MessageBox」と呼ばれる API 関数を探します。
DllImportAttribute クラスの現在の詳細については、.NET Framework 4 バージョンを確認した場所を参照してください。 DLLImportAttribute クラス
この .NET Framework 4 ページの「備考」セクションの重要なコメントは次のとおりです。
この属性は C# および C++ のメソッド定義に直接適用します。ただし、Visual Basic コンパイラは、Declare ステートメントを使用するときにこの属性を発行します。
したがって、少なくとも VB.NET に関しては、コンパイラは次のようになります。 Declare
とにかく発言。
このページには重要な注意事項もあります。
DllImportAttribute は、ジェネリック型のマーシャリングをサポートしていません。
したがって、ジェネリック型を使用したい場合は、 Declare
声明。
次に、Declare ステートメントの情報に進みました。Visual Studio 2010 バージョン (Visual Basic ステートメント情報) は次のとおりです。 宣言文
ここで重要な項目は次のメモでした。
Declare はモジュール レベルでのみ使用できます。これは、外部参照の宣言コンテキストはクラス、構造体、またはモジュールである必要があり、ソース ファイル、名前空間、インターフェイス、プロシージャ、またはブロックであってはいけないことを意味します。
どうやら、クラス、構造体、またはモジュールの外部で API 呼び出しを設定したい場合は、 Declare
.
例 Declare
このページのステートメントは次のとおりです。
Declare Function getUserName Lib "advapi32.dll" Alias "GetUserNameA" (
ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
この例の後には、次のちょっとした情報が続きます。
DllImportAttribute は、アンマネージ コードで関数を使用する別の方法を提供します。次の例では、Declare ステートメントを使用せずにインポートされた関数を宣言します。
もちろん、その後に DllImport の使用例が続きます。
Unicode と ANSI の結果に関して、この Declare ページによると、CharSet 値 (Declare で使用可能ですが、上記の例には示されていません) を指定すると、CLR は Unicode または ANSI のいずれかに対して、DllImport と同じタイプの自動名前検索を実行します。 ANSI。
CharSet 値を指定しない場合、 Declare
ステートメントを使用する場合は、Declare 内の関数名が実際の API 関数のヘッダー ファイル内の関数名と同じであることを確認するか、 Alias
(上記の例に示すように) ヘッダー ファイル内の実際の関数名と一致する値。
上記以外の状況では、DllImport と Declare のどちらかが優先される、または推奨されると述べた特定の Microsoft ドキュメントは見つかりませんでした。
したがって、私の結論は次のとおりです。
1) 定義を次の場所のいずれかに置く必要がある場合を除きます。 Declare
ステートメントは使用できません。どちらの手法でも問題なく機能します。
そして
2) DllImport を使用している場合は、必要な CharSet 値 (Unicode または ANSI) を必ず指定してください。指定しないと、予期しない結果が生じる可能性があります。
私の意見では、このキーワードは非推奨ではないようです。私が検索した結果によると、属性ではなくコンパイル時のキーワードを使用するだけです。
また、使用するときは、 Declare
, を書く必要はありません。 End Function
. 。その利点は、コードを次のように入力する必要がなく、関数インポートの宣言のモジュール全体を 1 行ずつ作成できることです。 DllImport
砂 End Function
s.
を使用して宣言すると、 Declare
キーワードを指定すると、コンパイラはこの関数を次のように扱います。 Shared
とにかく、他の外部オブジェクト経由でアクセスできるようになります。
しかし、現在の VB.NET では、両方とも同じターゲットを対象としており、パフォーマンスの違いはないと思います。これについては保証がありません。
したがって、私の結論は次のとおりです。DllImport の代わりに Declare を使用してください, 、特にあなたが引用したものを読むと、 マイクロソフトは述べた まれなケースで使用する必要があるということです。
次のオプションのいずれかを設定する必要がある場合は、次を使用します。 DllImportAttribute
属性、それ以外の場合は使用 Declare
. 。から https://msdn.microsoft.com/en-us/library/w4byd5y4.aspx
BestFitMapping、CallingConvention、ExactSpelling、Preservesig、SetLasterRor、またはThrowOnunMmappableCharフィールドをMicrosoft Visual Basic 2005宣言に適用するには、宣言ステートメントの代わりにDllimportattribute属性を使用する必要があります。
上記の参照は .NET 4.5 の記事からのものであるため、これが「Visual Basic 2005」にのみ適用されるかどうかは、上記の参照だけでは不明です。しかし、こんな記事も見つけました(https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute(v=vs.110).aspx )これは、 DllImportAttribute
.NET 4.5のクラス:
Visual Basicコンパイラは、宣言ステートメントを使用するときにこの属性を発します。 BestFitMapping、CallingConvention、ExactSpelling、Preservesig、SetlasterRor、またはThrowOnunMappableCharフィールドを含む複雑なメソッド定義については、この属性を視覚的な基本メソッド定義に直接適用します。.
これは、 Declare
オプションは、次のように変換される VB.net 構文糖衣です。 DllImportAttribute
コンパイル時に、使用時の正確なシナリオの概要を説明します。 DllImportAttribute
直接お勧めします。