dll aus C in vb.net aufrufen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 129 Antworten in diesem Thema. Der letzte Beitrag () ist von tron25.

    tron25 schrieb:

    wo schreibe ich die Klassen hin?
    Ganz einfach: Projekt im Projektmappen Explorer auswählen -> Strg + Shift + A drücken -> Klasse (oder "Class") auswählen -> Namen vergeben -> Code einfügen

    tron25 schrieb:

    In ein Modul oder in die Form?
    Ein Modul ist eine statische Klasse. D.h. du kannst keine Instanzen davon erzeugen. Das ganze kommt aus VBS/VB6, wo es noch keine Klassen gab, man aber separieren wollte. Eine Form ist - wenn du z.b. ein Windows Forms Projekt anlegst, lediglich eine Klasse, die von der Klasse System.Windows.Forms erbt. Die kannst du dann selber (beliebig) mit Elementen voll-kleistern ;D
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator Jou.

    tron25 schrieb:

    wo schreibe ich die Klassen hin?
    Manchmal ist es echt interessant, sich die Menüpunkte des Studios zu Gemüte zu führen.
    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!
    @RodFromGermany Der TE benutzt eine Braille-Zeile / Screenreader. (Sinngemäße) Aussagen wie "sieht man im Menü" halte ich in diesem Zusammenhang für zynisch - das muss nicht sein, auch wenns keine Absicht war. Er müsste sich für das "sehen" wohl erst alle (!) Menüs vorlesen lassen. Daher ist auch das gepostete Bild vermutlich wenig hilfreich...
    Gruß
    hal2000
    Hallo,
    erst einmal möchte ich sagen, daß Begriffe wie Sehen, Schauen, Betrachten, Gucken usw. auch für mich und andere Sehbehinderte oder Blinde alltägliche Redewendungen sind. Jeder sagt beispielsweise "Auf Wiedersehen!", egal, ob er es kann oder nicht. Allerdings muß ich zugeben, daß Bildbeispiele, zumindest für mich, tatsächlich nicht optimal sind ;-).

    Das ich eine Klasse über das Menü hinzufügen kann, da hätte ich auch selber drauf kommen können. Ich kann verstehen, daß manche Fragen etwas seltsam erscheinen für Jemanden, der schon so lange programmiert. Leider ist dieses Programm nicht meine einzige Aufgabe. Da kann es schon mal passieren, das man schneller eine Frage stellt, als man überlegen kann.

    So, ich habe nun eine Klasse erstellt und folgenden Code eingetragen:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Imports System.Text
    3. Public Class LouTranslator
    4. Public Shared Function Translate(input As String) As String
    5. If String.IsNullOrEmpty(input) Then
    6. Throw New ArgumentNullException("input")
    7. End If
    8. Dim buffer As New StringBuilder ' Auto-resize
    9. Dim refLength As Int32 = input.Length + 32 ' size heuristic
    10. NativeMethods.lou_translateString("de-de-g2.ctb", input, input.Length, buffer, refLength, Nothing, Nothing, 0)
    11. ' Limit stringBuilder size in case of implicit memory reallocation
    12. buffer.Length = refLength
    13. Return buffer.ToString()
    14. End Function
    15. End Class
    16. Public Class NativeMethods
    17. 'int EXPORT_CALL lou_translateString
    18. '(const char *tableList,
    19. ' const widechar *inbuf,
    20. ' int *inlen,
    21. ' widechar * outbuf,
    22. ' int *outlen,
    23. ' char *typeform,
    24. ' char *spacing,
    25. ' int mode);
    26. <DllImport("liblouis-2.dll")>
    27. Public Shared Function lou_translateString(
    28. <MarshalAs(UnmanagedType.LPStr)> tableList As String,
    29. <MarshalAs(UnmanagedType.LPWStr)> inbuf As String,
    30. ByRef inlen As Int32,
    31. <MarshalAs(UnmanagedType.LPWStr), Out()> outbuf As StringBuilder,
    32. ByRef outlen As Int32,
    33. <MarshalAs(UnmanagedType.LPStr)> typeform As String,
    34. <MarshalAs(UnmanagedType.LPStr)> spacing As String,
    35. mode As Int32) As Int32
    36. End Function
    37. End Class


    Die "Sub Main" habe ich in mein globales Modul eingefügt.

    In die Funktion "TextUebersetzen" habe ich folgendes eingetragen:

    VB.NET-Quellcode

    1. GekuerztText.Text = LouTranslator.Translate(UngekuerztText.Text)


    Die Funktion läuft ohne Absturz durch. Allerdings bleibt das Feld "Gekuerzttext.text" leer.

    Was bedeutet die Zeile:

    VB.NET-Quellcode

    1. Debug.Assert(LouTranslator.Translate("Wochenende") = "Wo4ccde")


    Ich möchte selbst einen Text übergeben und das Ergebnis zurückbekommen.

    Die folgenden Grafiken zeigen ein Beispiel.
    Bilder
    • Bild1.png

      59,1 kB, 1.600×1.200, 85 mal angesehen
    • Bild2.png

      58,2 kB, 1.600×1.200, 93 mal angesehen
    • Bild3.png

      44,64 kB, 1.600×1.200, 92 mal angesehen

    tron25 schrieb:

    Was bedeutet die Zeile:
    Das ist zum Vergleichen der Ausgabe mit dem erwarteten Ergebnis.

    Debug ist die Klasse, mit der man auf einer Konsole in Visual Studio "Debugwerte" ausgeben kann. Und mit der Funkton Asset kann man testen, ob das erhaltene Ergebnis dem erwarteten entspricht. Die Ausgabe ist je nach Ergebnis True oder False.

    tron25 schrieb:

    Die Funktion läuft ohne Absturz durch. Allerdings bleibt das Feld "Gekuerzttext.text" leer.
    Das liegt daran, dass du dein Code 1:1 kopiert und nicht bedacht hast, den Pfad zu der Übersetzungstabelle anzugeben. Wenn du den Code so ausführst, dann sucht die Exe im Ausführungsverzeichnis nach einer Datei de-de-g2.ctb. Die gibt es aber (im Normalfall) nicht. Du musst erst den Pfad angeben. Wie in deinem ersten Post mit Programmverzeichnis. Am besten erstellst du dir den Pfad, wie ich geschrieben habe, mit Hilfe der Klasse Path aus dem Namespace System.IO. Die Klasse bietet die Funktion Combine(), welche eine beliebige Anzahl von String Parametern annimmt. Dieser kannst du dann deine Variablen Programmverzeichnis und "\Braille\Brailletabellen\" sowie den Namen der Übersetzungstabelle übergeben. Als Ergebnis erhälst du dann einen String, der den Pfad repräsentiert. Diesen kannst du dann verwenden.

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Hallo,

    In der Funktion "Translator" habe ich folgende zeile aktualisiert:

    VB.NET-Quellcode

    1. NativeMethods.lou_translateString(Programmverzeichnis & "\Braille\Brailletabellen\" & AktuelleUebersetzungstabelle, input, input.Length, buffer, refLength, Nothing, Nothing, 0)


    Wenn ich die Funktion Translator schrittweise ausführe, sehe ich, daß in Buffer.ToString der übersetzte Text steht.

    In der Funktion "TextUebersetzen" führe ich folgende Anweisung aus:

    VB.NET-Quellcode

    1. GekuerztText.Text = LouTranslator.Translate(UngekuerztText.Text).


    Leider bleibt GekuerztText.Text immernoch leer.

    Ich dachte, daß die Zeile:

    VB.NET-Quellcode

    1. Return buffer.ToString()

    automatisch den Zielstring beim Aufruf der Funktion zurückgibt.

    Wie muß der Funktionsaufruf lauten, damit der gekürzte Text in GekuerztText.text ausgegeben wird?
    Lass dir mal ausgeben, was das Ergebnis der Funktion NativeMethods.lou_translateString() ist.
    Sollte es 0 sein, wird es irgendwie an den den Parametern liegen.

    Und anschließend lass dir das Ergebnis von LouTranslator.Translate(UngekuerztText.Text) im Debug-Fenster/MessageBox ausageben.
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    tron25 schrieb:

    Was bedeutet die Zeile:
    Dies ist ein Debug-Hilfsmittel. Wenn der erwartete Ausdruck rauskomt, passiert nix, ansonsten kommt ein entsprechender Dialog.
    Gugst Du hier.
    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!
    Hallo,
    Sorry für meine letzte Frage. Der Fehler lag in meinem Quellcode.
    Die Funktion "TextUebersetzen" wird von mehreren Stellen aus aufgerufen. Ich habe in dieser Funktion nach der Übersetzung ein "Exit Sub" geschrieben und nicht daran gedacht, daß das Programm nach dieser Zeile nicht nur den restlichen Code verläßt, sondern auch wieder zurück in die übergeordnete Funktion zurückgeht. Dort wird die Variable der alten Version wieder in "GekuerztText.text" geschrieben. Nachdem ich die entsprechende Zeile auskommentiert hatte, hat es auch geklappt.

    Vielen, vielen, vielen Dank an alle, die mir geholfen haben.

    Bis bald, denn ich befürchte, daß das nicht das letzte Problem war.

    P.S.: Dieses Forum ist echt SUPER. Macht weiter so!
    Hallo,

    ich habe festgestellt, daß ich keine längeren Texte in Kurzschrift übersetzen lassen kann. Wenn ich den folgenden Text eingebe, funktioniert es noch:

    hallo welt. heute ist mittwoch. morgen ist donnerstag. danach fänht das wochenende an. Anschließend beginnt die neu

    Schreibe ich aber einen weiteren Buchstaben dazu und lasse den Text übersetzen, stürzt das programm ab, sobald ich eine beliebige Taste (außer den Cursortasten) drücke. Es erscheint keine Fehlermeldung. Auch bei einer Mausbewegung stürzt das Programm ab. Wenn der Text aber kurz genug ist, geschiet nichts, bzw. das Programm macht das, was es soll.

    Woran kann das liegen?
    Ich vermute mal, dass der StringBuilder kein AutoResize hat zumindest nicht beim verwenden in einer nativen Methode(wär mir zumindest auch neu).

    Wie wärs wenn du die Capacity des StringBuilders(in dessen Konstruktor) angibst, ich denke refLength dürfte da das richtige sein.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Folgende Klassen habe ich:

    VB.NET-Quellcode

    1. Public Class LouTranslator
    2. Public Shared Function Translate(input As String) As String
    3. If String.IsNullOrEmpty(input) Then
    4. Throw New ArgumentNullException("input")
    5. End If
    6. Dim buffer As New StringBuilder ' Auto-resize
    7. Dim refLength As Int32 = input.Length + 32 ' size heuristic
    8. NativeMethods.lou_translateString(Programmverzeichnis & "\Braille\Brailletabellen\" & AktuelleUebersetzungstabelle, input, input.Length, buffer, refLength, Nothing, Nothing, 0)
    9. ' Limit stringBuilder size in case of implicit memory reallocation
    10. buffer.Length = refLength
    11. Return buffer.ToString()
    12. End Function
    13. End Class
    14. Public Class NativeMethods
    15. 'int EXPORT_CALL lou_translateString
    16. '(const char *tableList,
    17. ' const widechar *inbuf,
    18. ' int *inlen,
    19. ' widechar * outbuf,
    20. ' int *outlen,
    21. ' char *typeform,
    22. ' char *spacing,
    23. ' int mode);
    24. <DllImport("liblouis-2.dll", BestFitMapping:=True, ThrowOnUnmappableChar:=True, CharSet:=CharSet.Unicode)>
    25. Public Shared Function lou_translateString(
    26. <MarshalAs(UnmanagedType.LPStr)> tableList As String,
    27. <MarshalAs(UnmanagedType.LPWStr)> inbuf As String,
    28. ByRef inlen As Int32,
    29. <MarshalAs(UnmanagedType.LPWStr), Out()> outbuf As StringBuilder,
    30. ByRef outlen As Int32,
    31. <MarshalAs(UnmanagedType.LPWStr)> typeform As String,
    32. <MarshalAs(UnmanagedType.LPWStr)> spacing As String,
    33. mode As Int32) As Int32
    34. End Function
    35. End Class
    @tron25 Eigentlich nicht.
    Bei TextBoxen musst Du ein Environment.Newline als Zeilenschaltung einfügen.
    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!
    Frage: Warum verwendest du dann Zeilenumbrüche?
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    tron25 schrieb:

    Ich habe jetzt "VbCrLf" durch "Environment.NewLine" ersetzt.
    Poste mal den relevanten Code.
    - Einfügen von Zeilenumbrüchen,
    - Übersetzen,
    - Darstellen.
    Mach ggf. ein kleines Projekt, das den Effekt reproduzuert.
    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!