WindowsAPI - Wie richtig aufrufen?

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von nikeee13.

    WindowsAPI - Wie richtig aufrufen?

    Hi, eine kleine Frage:

    Existiert ein (funktionaler) Unterschied, ob ich eine WindowsAPI nutzende Funktion so

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. [...]
    3. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    4. Public Shared Function Irgendwas(ByVal Parameter As IntPtr) As Boolean
    5. End Function

    oder so

    VB.NET-Quellcode

    1. Private Declare Function Irgendwas Lib "user32.dll" (ByVal Parameter As IntPtr) As Boolean

    deklariere?
    Eins is die richtige Deklaration von .NET und das andere alter VB6 dreck.
    PS: und durch die Parameter die man bei der .NET Deklaration angeben kann, hat man mehr möglichkeiten die richtige Funktion aus Library zu deklarieren und eben auch Charset usw. anzugeben oder mit Errors umgegangen werden soll.
    @-= Christopher =-: Mit der .NET-Deklaration ist es sogar möglich, Überladungen derselben API-Funktion mit unterschiedlichen .NET-Parametern zu generieren, z.B. API.SendMessage().
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    ich kann mit DllImport nicht wirklich was anfangen, jetzt habichmal MSDN geguckt, und fund:

    MSDN schrieb:

    Der Visual Basic-Compiler gibt dieses Attribut jedoch bei Verwendung der Declare-Anweisung aus.
    womit imo geklärt ist, dass olle Declare-Anweisung eine vereinfachte Anwendung des DllImport - Attributs ist.

    nu mussich sagen, dass mir die durch dieses Attribut verfügbar gemachten Member garnix sagen: BestFitMapping, CallingConvention, CharSet, EntryPoint, ExactSpelling, PreserveSig, SetLastError, ThrowOnUnmappableChar
    ?(
    Wattn fürne CallingConvention? wattn fürn Charset?

    Daher ists mir ganz egal, ob ich olle Declare-Anweisung oder DllImport-Attribute verwende.
    Falls letzteres, dann ohne jede Member-Angabe, denn scheinbar sind die Default-Einstellungen, wie sie auch vonne Declare-Anweisung generiert werden, gut und zuverlässig, und was man nicht versteht, soll man die Finger von lassen.

    @Rod: Was meinst du mit Überladung - kannste mal Beispiel machen?
    Wenn es in Vb6 verwendet wird nicht, aber dass das .NET Framework diese Altlasten noch mitschleppt ist für alle negativ. Die Noobs finden Scripte mit VB6 Funktionen die meist viel schlechter funktionieren als das .NET äquivalent, oder mit .NET Methoden ists deutlich kürzer und perfomanter. Ebenso schleichen sich mit den VB6 Funktionen oft Fehler ein wegen falscher Datentypen. Glaub mir, ich bin hier schon lange unterwegs und sehe seit jahren wie Neulinge mit .NET Proggen und ihr Programmcode sieht nach VB6 aus und dann wundern sie sich wieso nichts funktioniert und deshalb bezeichne ich es als Dreck. Ein Trabi bringt mich auch von A nach B irgendwie, aber is Laut, Langsam, macht viel schädliche Abgase und stinkt, ist also ach Dreck weil Alt.
    Oder andere Metaphern, die Kirche, die GEMA, alles hält an etwas Alten fest, ist nicht mehr Zeitgemäß und somit ebenso Dreck.

    Dodo schrieb:

    Die Noobs finden Scripte mit VB6 Funktionen die meist viel schlechter funktionieren als das .NET äquivalent, oder mit .NET Methoden ists deutlich kürzer und perfomanter.

    Das - habe ich doch aufgezeigt - trifft in diesem Falle nicht zu.
    Die Declare-Anweisung verwendet DllImport, und ist allerdings bisserl kürzer zu formulieren.

    Nicht alles alte ist Dreck.

    ErfinderDesRades schrieb:

    kannste mal Beispiel machen?
    So was hier:

    VB.NET-Quellcode

    1. <DllImport("user32.dll", CharSet:=CharSet.Unicode)> _
    2. Public Shared Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr
    3. End Function
    4. <DllImport("user32.dll", EntryPoint:="SendMessageA", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
    5. Public Shared Function SendMessageByInt(ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    6. End Function
    7. <DllImport("user32.dll", EntryPoint:="SendMessageA", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
    8. Public Shared Function SendMessageByString(ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As IntPtr, <MarshalAs(UnmanagedType.VBByRefStr)> ByRef lParam As String) As Integer
    9. End Function
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    sehe nicht, dass olle Declare das nicht könnte:

    VB.NET-Quellcode

    1. Declare Function SendMessage Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr
    2. Declare Function SendMessageByInt Lib "user32.dll" Alias "SendMessage" ( _
    3. ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    4. Declare Function SendMessageByString Lib "user32.dll" Alias "SendMessage" ( _
    5. ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As IntPtr, <MarshalAs(UnmanagedType.VBByRefStr)> ByRef lParam As String) As Integer
    also glaubich jdfs, dasses so geht - is jetzt ungetestet

    Dodo schrieb:

    Die Noobs finden Scripte mit VB6 Funktionen die meist viel schlechter funktionieren als das .NET äquivalent, oder mit .NET Methoden ists deutlich kürzer und perfomanter.
    Das Schlechte an den übernommen Deklarationen aus VB6 ist, dass die Datentypen damals alle nur halb so breit waren. Das ist der Grund, warum das meistens nicht so einfach geht. (Ein Integer war z. B. 16 Bit und nicht 32).

    ErfinderDesRades schrieb:

    nu mussich sagen, dass mir die durch dieses Attribut verfügbar gemachten Member garnix sagen: BestFitMapping, CallingConvention, CharSet, EntryPoint, ExactSpelling, PreserveSig, SetLastError, ThrowOnUnmappableChar
    ?(
    Wattn fürne CallingConvention? wattn fürn Charset?
    Die Calling Convention sagt aus, wie eine native Methode aufgerufen und wie der Rückgabewert geholt wird. Eine Calling Convention ist z. B. cdecl. Das kann uns Managed-programmierer eigentlich völlig egal sein, spielt aber eine Rolle bei Platform Invokes. Bei SetLastError würde ich vermuten, dass man dort festlegen kann, ob bei einem Fehler der LastError gesetzt werden soll oder nicht. Steht bestimmt in der Dokumentation.
    Generell sind diese "Tweaks" sehr wichtig, um mit Funktionsaufrufen verschiedenster Art umgehen zu können.

    Wahrscheinlich ist es eher die Abwärtskompatibilität zu VB6 als eine unbedingt erwünschte VB.NET-Eigenschaft. Genau das gleiche Prinzip ist bei Sachen wie MsgBox() oder InputBox() verwendet worden - Der Compiler wurstelt das einfach auf interne .NET-Sachen um. Mit anderen Worten: Für VB wird nicht das .NET-Konzept umgestaltet, sondern eher umgekehrt.

    Ich muss aber ehrlich sagen, dass ich das "End Function" bei der DllImport-Variante eher unschön finde. Das macht C# mit einer "Mischung" aus beiden besser:

    C-Quellcode

    1. [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    2. public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
    Dort ist kein nerviges "{}". Stattdessen das Schlüsselwort extern (ähnlich dem Declare).

    Ich würde das favorisieren:

    VB.NET-Quellcode

    1. <DllImport("user32.dll", CharSet:=CharSet.Unicode)>
    2. Public Shared Declare Function SendMessage(ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Aber Microsoft wird wohl seinen Grund gehabt haben, es nicht so zu machen.

    @Rod:
    Statt SendMessageA einfach SendMessageW verwenden, dann geht auch das Unicode-Charset.
    Wenn du den EntryPoint weg lässt, das CharSet auf CharSet.Auto stellst und die Funktion so benennst wie den Typedef auf MSDN, dann matcht er alles von alleine. Genau so sollte es(?) der Vorschlag von EDR aufgrund des Alias "SendMessage" machen.
    Von meinem iPhone gesendet

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „nikeee13“ () aus folgendem Grund: Qualitätsverbesserungen