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.

    <p>Vielen Dank, es funktioniert.</p>

    <p>&nbsp;</p>

    <p>Ich habe mir das Beispiel aus Post 2 heruntergeladen und angeschaut. Ich mu&szlig; zugeben, dass ich noch nicht den vollen Durchblick habe. &quot;lou_version&quot; gibt einen Pointer zur Version im Speicher zur&uuml;ck, daher wird das Ergebnis &uuml;ber &quot;MarshalAs.PTRToString&quot; in einen String umgewandelt. Allerdings habe ich ein Problem, dies auf eine Funktion mit mehreren Eingabe- und Ausgabewerten zu &uuml;bertragen. So komme ich wieder auf die eigentliche Funktion zur&uuml;ck:</p>

    <p>

    VB.NET-Quellcode

    1. </p>
    2. <p>Imports System.Globalization<br />
    3. Imports System.Runtime.InteropServices<br />
    4. Imports System.Text<br />
    5. Class LibLouis<br />
    6. &nbsp;&nbsp;&nbsp; Public Shared Function Translate(Input As String) As String<br />
    7. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim InputLen As Int32 = Input.Length<br />
    8. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim OutputLen As Int32 = Input.Length * 32<br />
    9. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim Output As New StringBuilder<br />
    10. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim typeform() = Enumerable.Repeat(NativeMethods.Typeforms.plain_text, OutputLen).ToArray()<br />
    11. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim Adresse = NativeMethods.lou_translateString(&quot;\braille\Brailletabellen\de-g2.ctb&quot;, Input, InputLen, Output, OutputLen, Nothing, Nothing, 0)<br />
    12. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim Rueckgabe As String = Marshal.PtrToStringAnsi(Adresse)<br />
    13. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return Rueckgabe<br />
    14. &nbsp;&nbsp;&nbsp; End Function</p>
    15. <p>End Class</p>
    16. <p>Class NativeMethods<br />
    17. &nbsp;&nbsp;&nbsp; &lt;DllImport(&quot;liblouis.dll&quot;, BestFitMapping:=False, ThrowOnUnmappableChar:=True, CharSet:=CharSet.Auto)&gt;<br />
    18. &nbsp;&nbsp;&nbsp; Public Shared Function lou_version() As Integer<br />
    19. &nbsp;&nbsp;&nbsp; End Function</p>
    20. <p>&nbsp;&nbsp;&nbsp; &lt;DllImport(&quot;liblouis.dll&quot;, BestFitMapping:=False, ThrowOnUnmappableChar:=True, CharSet:=CharSet.Auto)&gt;<br />
    21. &nbsp;&nbsp;&nbsp; Public Shared Function lou_translateString(<br />
    22. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;MarshalAs(UnmanagedType.LPStr)&gt; tableList As String,<br />
    23. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;MarshalAs(UnmanagedType.LPWStr)&gt; inbuf As String,<br />
    24. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ByRef inlen As Int32,<br />
    25. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;MarshalAs(UnmanagedType.LPWStr), Out()&gt; outbuf As StringBuilder,<br />
    26. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ByRef outlen As Int32,<br />
    27. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Typeform() As Typeforms,<br />
    28. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;MarshalAs(UnmanagedType.LPStr)&gt; spacing As String,<br />
    29. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mode As Int32) As Integer<br />
    30. &nbsp;&nbsp;&nbsp; End Function<br />
    31. &nbsp;&nbsp;&nbsp; Public Enum TranslationModes<br />
    32. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; noContractions = 1<br />
    33. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compbrlAtCursor = 2<br />
    34. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dotsIO = 4<br />
    35. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; comp8Dots = 8<br />
    36. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass1Only = 16<br />
    37. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compbrlLeftCursor = 32<br />
    38. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; otherTrans = 64<br />
    39. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ucBrl = 128<br />
    40. &nbsp;&nbsp;&nbsp; End Enum</p>
    41. <p>&nbsp;&nbsp;&nbsp; Public Enum Typeforms As UShort<br />
    42. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; plain_text = &amp;H0<br />
    43. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; italic = &amp;H1&nbsp;&nbsp;&nbsp;&nbsp; ' emph_1<br />
    44. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; underline = &amp;H2&nbsp; ' emph_2<br />
    45. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bold = &amp;H4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ' emph_3<br />
    46. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emph_4 = &amp;H8<br />
    47. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emph_5 = &amp;H10<br />
    48. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emph_6 = &amp;H20<br />
    49. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emph_7 = &amp;H40<br />
    50. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emph_8 = &amp;H80<br />
    51. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emph_9 = &amp;H100<br />
    52. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emph_10 = &amp;H200<br />
    53. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; computer_braille = &amp;H400<br />
    54. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; no_translate = &amp;H800<br />
    55. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; no_contract = &amp;H1000<br />
    56. &nbsp;&nbsp;&nbsp; End Enum<br />
    57. End Class</p>
    58. <p>
    </p>

    <p>&nbsp;</p>

    <p>Aus reiner Verzweifelung habe ich versucht, mit den Variablendeklarationen herumzuexperimentieren. So habe ich beispielsweise &quot;&lt;MarshalAs()&gt;&quot; durch &quot;byRef&quot; ersetzt und anderes ausprobiert. Tuvok hat mal gesagt: &quot;Wenn das M&ouml;gliche ausgesch&ouml;pft ist, bleibt nur das Unm&ouml;gliche &uuml;brig&quot;. Spa&szlig; bei Seite! Ich habe sogar die DLL mit &quot;nmake&quot; und &quot;Clang&quot; erneut kompiliert. Ich verstehe nicht, warum trotz gleicher Deklarationen die alte Version 3.0.0 funktioniert und die Neue nicht. Eine Idee, wie &quot;lou_translate&quot; bzw. &quot;lou_translateString&quot; ver&auml;ndert werden m&uuml;ssen?</p>
    Ich weiß nicht, warum sich die HTML-Tags einschleichen, wenn ich Text aus dem VB-Editor hineinkopiere. Jedesmal, muß ich den Text in den Editor kopieren, die Tags entfernen und wieder zurückschreiben. So nun die richtige Version:

    Vielen Dank, es funktioniert.

    Ich habe mir das Beispiel aus Post 2 heruntergeladen und angeschaut. Ich muß zugeben, dass ich noch nicht den vollen Durchblick habe. "lou_version" gibt einen Pointer zur Version im Speicher zurück, daher wird das Ergebnis über "MarshalAs.PTRToString" in einen String umgewandelt. Allerdings habe ich ein Problem, dies auf eine Funktion mit mehreren Eingabe- und Ausgabewerten zu übertragen. So komme ich wieder auf die eigentliche Funktion zurück:

    VB.NET-Quellcode

    1. Imports System.Globalization
    2. Imports System.Runtime.InteropServices
    3. Imports System.Text
    4. Class LibLouis
    5. Public Shared Function Translate(Input As String) As String
    6. Dim InputLen As Int32 = Input.Length
    7. Dim OutputLen As Int32 = Input.Length * 32
    8. Dim Output As New StringBuilder
    9. Dim typeform() = Enumerable.Repeat(NativeMethods.Typeforms.plain_text, OutputLen).ToArray()
    10. Dim Adresse = NativeMethods.lou_translateString("\braille\Brailletabellen\de-g2.ctb", Input, InputLen, Output, OutputLen, Nothing, Nothing, 0)
    11. Dim Rueckgabe As String = Marshal.PtrToStringAnsi(Adresse)
    12. Return Rueckgabe
    13. End Function
    14. End Class
    15. Class NativeMethods
    16. <DllImport("liblouis.dll", BestFitMapping:=False, ThrowOnUnmappableChar:=True, CharSet:=CharSet.Auto)>
    17. Public Shared Function lou_version() As Integer
    18. End Function
    19. <DllImport("liblouis.dll", BestFitMapping:=False, ThrowOnUnmappableChar:=True, CharSet:=CharSet.Auto)>
    20. Public Shared Function lou_translateString(
    21. <MarshalAs(UnmanagedType.LPStr)> tableList As String,
    22. <MarshalAs(UnmanagedType.LPWStr)> inbuf As String,
    23. ByRef inlen As Int32,
    24. <MarshalAs(UnmanagedType.LPWStr), Out()> outbuf As StringBuilder,
    25. ByRef outlen As Int32,
    26. Typeform() As Typeforms,
    27. <MarshalAs(UnmanagedType.LPStr)> spacing As String,
    28. mode As Int32) As Integer
    29. End Function
    30. Public Enum TranslationModes
    31. noContractions = 1
    32. compbrlAtCursor = 2
    33. dotsIO = 4
    34. comp8Dots = 8
    35. pass1Only = 16
    36. compbrlLeftCursor = 32
    37. otherTrans = 64
    38. ucBrl = 128
    39. End Enum
    40. Public Enum Typeforms As UShort
    41. plain_text = &amp;H0
    42. italic = &amp;H1 ' emph_1
    43. underline = &amp;H2 ' emph_2
    44. bold = &amp;H4 ' emph_3
    45. emph_4 = &amp;H8
    46. emph_5 = &amp;H10
    47. emph_6 = &amp;H20
    48. emph_7 = &amp;H40
    49. emph_8 = &amp;H80
    50. emph_9 = &amp;H100
    51. emph_10 = &amp;H200
    52. computer_braille = &amp;H400
    53. no_translate = &amp;H800
    54. no_contract = &amp;H1000
    55. End Enum
    56. End Class


    Aus reiner Verzweifelung habe ich versucht, mit den Variablendeklarationen herumzuexperimentieren. So habe ich beispielsweise "<MarshalAs()>" durch "byRef" ersetzt und anderes ausprobiert. Tuvok hat mal gesagt: "Wenn das Mögliche ausgeschöpft ist, bleibt nur das Unmögliche übrig". Spaß bei Seite! Ich habe sogar die DLL mit "nmake" und "Clang" erneut kompiliert. Ich verstehe nicht, warum trotz gleicher Deklarationen die alte Version 3.0.0 funktioniert und die Neue nicht. Eine Idee, wie "lou_translate" bzw. "lou_translateString" verändert werden müssen?

    tron25 schrieb:

    Eine Idee, wie "lou_translate" bzw. "lou_translateString" verändert werden müssen?
    Mach mal ein kleines Demo-Projekt mit entsprechenden Testdaten.
    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!
    Hier ist ein kleines Testprogramm. Im Hauptverzeichnis befindet sich eine html-Datei mit den Funktionsbeschreibungen. In das linke Eingabefeld wird ein Wort eingetragen. Danach wählt man aus der Ausklappliste eine Übersetzungsmethode aus. Nachdem dann auf "Übersetzen" geklickt wurde, sollte im rechten Eingabefeld das übersetzte Wort stehen. Wählt man beispielsweise "German contracted" aus, so wird aus dem Wort "Wochenende" das Wort "wo4ccde". Dies ist eine Art von Stenographie in Blindenschrift. Aus dem Wort "hallo" sollte dann "haqo" werden, usw. Bisher erscheint bei meinen Versuchen nur ein "*" bei ungekürzter Schreibweise und ein "$" bei Gekürzter. Vermutlich wird nur das erste Zeichen berücksichtig und auch nur eins zurückgegeben. Bzw. wird nur der Anfang des Speicherbereiches angegeben und ich weiß nicht, wie ich ab dieser Stelle den Rest auslesen kann.
    Dateien
    • LibLouis Test.zip

      (4,84 MB, 22 mal heruntergeladen, zuletzt: )
    @tron25 Ich werfe das Handtuch. lou_translateString() hat etwas sehr viele Parameter, die alle korrekt gemanaged werden müssen.
    Warum verwendest Du nicht die alte offensichtlich funktionierende DLL?
    Vielleicht solltest Du Dich doch mal an den Hersteller wenden.
    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!
    Die alte DLL ist alt. Seit dem gab es viele Neuerungen bezüglich beispielsweise der Rückübersetzung von der Kurzschrift in die Vollschrift. Liblouis ist ein opensource-Projekt. Ich habe schon in die Newsgroup geschrieben. So, wie es scheint, bin ich der Einzige, der die DLL in ein VB-Projekt eingebunden hat.

    Vielen Dank für deine Hilfe. Da du mir den richtigen Weg mit "lou_version" gezeigt hast, bin ich zuversichtlich, dass es auch einen richtigen Weg für die anderen Funktionen gibt.
    @tron25 Wenn das ein OpenSource-Projekt ist, kannst Du davon die Quellen organisieren?
    Da muss es ja auch ein Testprogramm geben.
    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!
    Hier findest du die neueste Version 3.24.0:
    github.com/liblouis/liblouis/releases
    Ich habe zwar
    die Pakete schon gedownloaded auf meinem PC. Aber ich weiß nicht,
    wieviel Speicherplatz ich bei VBParadise zur Verfügung habe. Derzeit
    verwende ich die 32bit-Version. Wenn es dann irgendwann funktioniert,
    möchte ich gerne auf die 64bit-Version umsteigen. Außerdem läuft die
    Version 3.0.0 auch nur im 32bit-Modus.


    So, nun habe ich die Lösung endlich gefunden. Diese lag darin, mit "nmake" die DLL neu zu kompilieren. Ich habe es mit der 32bit-DLL von 3.24 und 3.23 versucht. Beidesmal hat es mit den mitgelieferten Versionen nicht funktioniert. Mit der selbst kompilierten Version hat es einwandfrei geklappt. Für alle, denen ich damit helfen kann, hier die funktionierende Version.

    Vielen Dank an Alle, die mir geholfen haben.
    Dateien
    • LibLouis Test.zip

      (315,73 kB, 24 mal heruntergeladen, zuletzt: )