Frage

Ich stelle fest, in der MSDN-Dokumentation, dass es mehrere Möglichkeiten einen Verweis auf eine Funktion in einer externen DLL aus einem VB.NET-Programm deklarieren.

Die verwirrende Sache ist, dass MSDN behauptet, dass Sie nur die DllImportAttribute Klasse mit Gemeinschafts-Funktionsprototypen" in seltenen Fällen „aber ich konnte die Erklärung für diese Aussage nicht finden, während Sie einfach die Declare Stichwort statt.

Warum sind diese anders, und wo ich in geeigneter Weise jeden Fall verwenden?

War es hilfreich?

Lösung

Deklarieren ist wirklich ein Versuch, eine P zu halten / Syntax aufrufen, die besser vertraut sein würde, Visual Basic 6.0-Benutzer die Umstellung auf VB.NET . Es hat viele der gleichen Eigenschaften wie P / Invoke aber die Rangierung bestimmter Arten, insbesondere Strings, sind sehr unterschiedlich und kann ein wenig Verwirrung, um Menschen besser vertraut mit DllImport Regeln führen.

Ich bin mir nicht ganz sicher, was die Dokumentation in Anspielung auf die „selten“ Unterscheidung. Ich benutze DllImport in meinem Code häufig sowohl von VB.NET und C #, ohne Frage.

Im Allgemeinen würde ich DllImport verwendet über deklarieren, wenn Sie aus einem Visual Basic 6.0 Hintergrund kommen. Die Dokumentation und Beispiele für DllImport sind viel besser und es gibt viele Werkzeuge zur Erzeugung von Erklärungen DllImport ausgerichtet.

Andere Tipps

Anscheinend sind die Declare und DllImport Aussagen sind grundsätzlich die gleichen. Sie verwenden können, je nachdem, was Sie bevorzugen.

Es folgt eine Diskussion der wenigen Punkte, die ein wenig anders in jedem arbeiten können, die eine Vorliebe für einen über die andere beeinflussen können:

Ich begann mit einem Artikel von MSDN in Bezug auf Visual Studio 2003 betitelten Verwendung die DllImport Attribut . (Ein bisschen alt, aber da die DllImport Aussage scheint in .NET entstanden zu sein, schien es angebracht, an den Anfang zurück.)

Da ein Beispiel DllImport Aussage:

[DllImport("user32.dll", EntryPoint = "MessageBox", CharSet = Unicode)]
int MessageBox(void* hWnd, wchar_t* lpText, wchar_t* lpCaption, unsigned int uType);

Er sagt, dass, wenn der Wert Entrypoint ausgelassen wird, wird der CLR für den Namen der Funktion aussehen wird (MessageBox in diesem Fall) als Standard. Doch in diesem Fall, da ein CharSet von Unicode angegeben wurde, würde die CLR FIRST für eine Funktion suchen „MessageBoxW“ genannt - das ‚W‘ angibt, einen Unicode-Rückgabetyp. (Die ANSI-Rückgabetyp Version wäre „MessageBoxA“). Wenn kein „MessageBoxW“ gefunden wurde, dann ist die CLR für eine API-Funktion aufgerufen tatsächlich aussehen würde „MessageBox“.

Aktuelle Spezifika über die DllImportAttribute Klasse finden sich hier, wo ich das .NET Framework 4-Version angesehen: DllImportAttribute Klasse

Ein Schlüssel Kommentar im Bemerkung Abschnitt dieser .NET Framework 4 Seite ist, dass:

  

Sie wenden dieses Attribut direkt auf C # und C ++ Methodendefinitionen; jedoch die Visual Basic-Compiler gibt dieses Attribut, wenn Sie die Declare-Anweisung verwenden.

Also, zumindest so zu VB.NET bezieht, endet der Compiler ohnehin mit einer Declare Anweisung auf.

Es gibt auch einen wichtigen Hinweis auf dieser Seite:

  

Die DllImportAttribute nicht Serialisieren von generischen Typen unterstützen.

So scheint es, dass, wenn Sie einen generischen Typ verwenden möchten, sollten Sie eine Declare Anweisung verwenden.

Als nächstes ging ich zu den Declare-Anweisung Informationen. A Visual Studio 2010-Version (Visual Basic-Anweisung info) war hier: Statement Deklarieren

Ein Schlüsselpunkt hier war dieser Hinweis:

  

Sie können nur auf Modulebene deklarieren verwenden. Dies bedeutet, dass der Deklarationskontext für eine externe Referenz eine Klasse sein muss, eine Struktur oder Modul und kann nicht eine Quelldatei, Namensraum, Schnittstelle, eine Prozedur oder Block sein.

Anscheinend, wenn Sie einen API-Aufruf außerhalb einer Klasse, Struktur oder Modul einrichten möchten, werden Sie die DllImport Anweisung anstelle des Declare verwenden.

Das Beispiel Declare Aussage auf dieser Seite lautet:

Declare Function getUserName Lib "advapi32.dll" Alias "GetUserNameA" (
  ByVal lpBuffer As String, ByRef nSize As Integer) As Integer

, dieses Beispiel folgend ist dieser kleine Leckerbissen der Informationen:

  

Die DllImportAttribute bieten eine alternative Möglichkeit von Funktionen in nicht verwalteten Code. Das folgende Beispiel deklariert eine importierte Funktion ohne eine Declare-Anweisung.

, gefolgt von, natürlich, ein Beispiel für DllImport Nutzung.

In Bezug auf Unicode vs ANSI Ergebnisse nach dieser Declare Seite, wenn Sie einen CharSet-Wert (in Declare, aber nicht in dem oben gezeigten Beispiel) geben die CLR die gleiche Art der automatischen Namenssuche tun, den DllImport tut - für entweder Unicode oder ANSI.

Wenn Sie kein charset Wert in der Declare Anweisung angeben, dann müssen Sie sicherstellen, dass Ihre Funktionsnamen in der Declare ist der gleiche wie der Funktionsname in der aktuellen Header-Datei der API-Funktion, oder Sie müssen ein Alias Wert specifiy dass entspricht den aktuellen Funktionsnamen in der Header-Datei (wie im Beispiel oben).

War ich Angabe von spezifischen Microsoft-Dokumentation nicht finden können, dass entweder DllImport oder Deklarieren wurden bevorzugt oder sogar empfohlen, über eine über jene anderen in jeder Situation anders als zur Kenntnis genommen.

Mein Fazit ist also:

1) Es sei denn, Sie benötigen eine Definition in einer der Orte, eine Declare Anweisung nicht benutzt werden kann platzieren, entweder Technik wird funktionieren,

und

2), wenn Sie DllImport verwenden, stellen Sie sicher, dass Sie den CharSet Wert legen Sie (Unicode oder ANSI) wollen, oder Sie können unerwartete Ergebnisse erhalten.

Meiner Meinung nach, da dieses Schlüsselwort nicht deprected sieht, usw. aus dem, was ich gesucht, verwenden Sie einfach Kompilierung-Schlüsselwörter statt Attributen.

Auch wenn Sie die Declare verwenden, brauchen Sie nicht die End Function zu schreiben. Der Vorteil davon ist, dass Sie ein ganzes Modul der Erklärungen der Funktion importiert Zeile für Zeile erstellen, ohne dass Sie Ihren Code mit DllImports und End Functions pulute.

Wenn Sie das Declare Schlüsselwort Deklarieren der Compiler behandelt diese Funktion als Shared trotzdem, so kann es über andere extenal Objekte zugegriffen werden.

Aber ich denke, in den aktuellen VB.NET sind sie beide auf das gleiche Ziel gerichtet und keinen Performance-Unterschied -. Keine Garantie auf diesem

So ist meine Schlussfolgerung ist: Ist die Declare statt DllImport verwenden , besonders zu lesen, was Sie zitiert, dass Microsoft erklärte , dass es in seltenen Fällen verwendet werden soll.

Wenn benötigen Sie eine der folgenden Optionen zu setzen, dann DllImportAttribute Attribut, sonst Verwendung Declare verwenden. Aus https://msdn.microsoft.com/en-us/library/w4byd5y4. aspx

  

das BestFitMapping, Calling, ExactSpelling anwenden zu können,   PreserveSig, SetLastError oder ThrowOnUnmappableChar Felder ein   Microsoft Visual Basic 2005 Deklaration, müssen Sie die Verwendung   DllImportAttribute Attribut anstelle der Declare-Anweisung.

Es ist unklar, aus der oben genannten Referenz nur, ob dies auf „Visual Basic 2005“ nur gilt oder nicht, wie die obige Referenz von einem .NET 4.5 Artikel. Allerdings fand ich auch diesen Artikel (

scroll top