DLL in VB6 einbinden

  • VB6

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von tron225.

    DLL in VB6 einbinden

    Hallo,

    ich habe eine in C geschriebene DLL, die ich in VB6 einbinden möchte. Ich habe herausgefunden, daß ich nur Funktionen in VB deklarieren kann, die ich dann im Code benutzen kann. Die DLL enthält u.a. folgende Funktion:

    int lou_translateString (const char * tableList, const widechar * inbuf, int *inlen,
    widechar *outbuf, int *outlen, char *typeform, char *spacing, int mode);

    Diese Funktion wandelt einen String in eine Art Stenographie anhand von entsprechenden Tabellen um.

    tablelist ist der Pfad zu einer Übersetzungstabelle

    *inbuf ist ein Zeiger zu dem zu übersetzenden Text

    inlen ist die Länge des zu übersetzenden Textes

    *outbuf ist ein Zeiger zum übersetzten Text

    outlen ist die Länge des übersetzten Textes

    typeform ist ein Schriftattribut des Textes

    spacing ist die Leerzeichenbehandlung zwischen den beiden Texten

    mode zeigt, ob die Übersetztung komplett war

    Die originale englische Beschreibung ist unten angehängt.

    Ich habe folgende Verständnisprobleme:

    1. Wie deklariert man eine Wide Char Variable in VB6?

    2. Wie kann ich einen Zeiger-Parameter, z.B. *inbuf in VB übergeben?

    Ich habe in VB6 folgendes in ein Modul geschrieben:

    Public Declare Function lou_translateString Lib "d:\programmierung\punktbilder\braille\LibLouis.dll" _
    (ByVal tableList As String, ByVal inbuf As Long, inlen As Integer, ByVal outbuf As Long, _
    ByVal outlen As Integer, ByVal typeform As Long, spacing As Byte, mode As Integer) _
    As Integer

    In einem Formular habe ich zwei Textfelder (Text1Text, Text2Text) und eine Schaltfläche (Command1). Im Textfeld Text1Text steht der Quelltext. Das umgesetzte Ergebnis soll dann im Textfeld Text2Text stehen. In die Schaltfläche habe ich folgenden Code geschrieben:

    lou_translateString "d:\Programmierung\PunktBilder\Braille\Brailletabellen\de-de-g2.ctb", Text1Text, Len(Text1Text), Text2Text, Len(Text1Text), 0, 0, 0

    Die "CTB-Datei" ist die Übersetzungsdatei. Wenn ich den Code nun ausführe, bekomme ich den Fehlercode 13 und das die Typen unverträglich seien. Ich vermute, daß das Problem in den Datentüpen der Übergabeparameter liegt.

    Ich wäre über hilfreiche Antworten sehr dankbar.

    Danke

    Anhang:

    This function takes a string of 16-bit Unicode characters in `inbuf'
    and translates it into a string of 16-bit characters in `outbuf'. Each
    16-bit character produces a particular dot pattern in one braille cell
    when sent to an embosser or braille display or to a screen type font.
    Which 16-bit character represents which dot pattern is indicated by the
    character-definition and display opcodes in the translation table.

    The `tableList' parameter points to a list of translation tables
    separated by commas. If only one table is given, no comma should be
    used after it. It is these tables which control just how the
    translation is made, whether in Grade 2, Grade 1, or something else.

    liblouis knows where to find all the tables that have been
    distributed with it. So you can just give a table name such as
    `en-us-g2.ctb' and liblouis will load it. You can also give a table
    name which includes a path. If this is the first table in a list, all
    the tables in the list must be on the same path. You can specify a path
    on which liblouis will look for table names by setting the environment
    variable `LOUIS_TABLEPATH'. This environment variable can contain one or
    more paths separated by commas. On receiving a table name liblouis
    first checks to see if it can be found on any of these paths. If not,
    it then checks to see if it can be found in the current directory, or,
    if the first (or only) name in a table list, if it contains a path
    name, can be found on that path. If not, it checks to see if it can be
    found on the path where the distributed tables have been installed. If
    a table has already been loaded and compiled this path-checking is
    skipped.

    The tables in a list are all compiled into the same internal table.
    The list is then regarded as the name of this table. As explained in
    *Note How to Write Translation Tables::, each table is a file which may
    be plain text, big-endian Unicode or little-endian Unicode. A table (or
    list of tables) is compiled into an internal representation the first
    time it is used. Liblouis keeps track of which tables have been
    compiled. For this reason, it is essential to call the `lou_free'
    function at the end of your application to avoid memory leaks. Do _NOT_
    call `lou_free' after each translation. This will force liblouis to
    compile the translation tables each time they are used, leading to
    great inefficiency.

    Note that both the `*inlen' and `*outlen' parameters are pointers to
    integers. When the function is called, these integers contain the
    maximum input and output lengths, respectively. When it returns, they
    are set to the actual lengths used.

    The `typeform' parameter is used to indicate italic type, boldface
    type, computer braille, etc. It is a string of characters with the same
    length as the input buffer pointed to by `*inbuf'. However, it is used
    to pass back character-by-character results, so enough space must be
    provided to match the `*outlen' parameter. Each character indicates
    the typeform of the corresponding character in the input buffer. The
    values are as follows: 0 plain-text; 1 italic; 2 bold; 4 underline; 8
    computer braille. These values can be added for multiple emphasis. If
    this parameter is `NULL', no checking for type forms is done. In
    addition, if this parameter is not `NULL', it is set on return to have
    an 8 at every position corresponding to a character in `outbuf' which
    was defined to have a dot representation containing dot 7, dot 8 or
    both, and to 0 otherwise.

    The `spacing' parameter is used to indicate differences in spacing
    between the input string and the translated output string. It is also
    of the same length as the string pointed to by `*inbuf'. If this
    parameter is `NULL', no spacing information is computed.

    The `mode' parameter specifies how the translation should be done.
    The valid values of mode are listed in `liblouis.h'. They are all
    powers of 2, so that a combined mode can be specified by adding up
    different values.

    The function returns 1 if no errors were encountered and 0 if a
    complete translation could not be done.
    Auf Anhieb würde ich mal folgende Signatur ausprobieren:

    Visual Basic-Quellcode

    1. Private Declare Function lou_translateString Lib "hier der Name der DLL" (tableList As String, inbuf As String, inlen As Long, ByRef outbuf As String, ByRef outlen As Long, typeform As Byte, spacing As Byte, mode As Long) As Long

    Ein "int" ist ein 32Bit Integer. In VB6 ist "Integer" jedoch nur ein 16Bif Integer und "Long" ist ein 32Big Integer (das ist da anders als in .Net). Einen Char-Pointer ist normalerweise auch einfach als String zu übergeben, das wird dann automatisch gemarshalt, allerdings kenne ich das nur aus .Net und weiß daher nicht, ob es sich bei VB6 auch so verhält. Ein "char" steht für 8Bit, jedoch kann das sowohl im Sinne eines ACII-Zeichens alsauch im Sinne einer Zahl (also eines Bytes) sein. Ich hab jetzt einfach mal Byte angenommen, da ich nicht weiß, was von beiden hier benötigt wird.
    Erst einmal vielen Dank für die Schnelle Antwort.

    Deinen Vorschlag habe ich eingegeben und habe den folgenden Funktionsaufruf verwandt:

    lou_translateString "d:\Programmierung\PunktBilder\Braille\Brailletabellen\de-de-g2.ctb", Text1Text, Len(Text1Text), Text2Text, Len(Text1Text), 0, 0, 0

    Im C-Code steht aber beispielsweise^:

    const char * tableList,
    const widechar * inbuf,
    int *inlen,
    widechar *outbuf,
    int *outlen,
    char *typeform,
    char *spacing,
    int mode);

    Soweit ich weiß, ist ein widechar ein Doppelbyte. Und was ist der Unterschied zwischen "char" und einem "const char"?

    tron225 schrieb:

    was ist der Unterschied zwischen "char" und einem "const char"?
    Sozusagen ein beschreibbarer und ein nicht beschreibbarer String.
    Const = "unveränderlich". Da passt der Compiler auf.
    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!

    tron225 schrieb:

    Was bedeutet "byref" von "outbuf as string"?
    Kannst Du bitte mal alle Fragen dieser Art zusammenfassen?
    ByRef heißt (im Gegensatz zu ByVal), dass eine Referenz des Wertes (also ein Pointer auf) übergeben wird, so dass der Wert vom aufgerufenen geändert werden kann.
    ByVal - Es wird eine Kopie des Wertes übergeben.
    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!
    Im Eingabefeld für den Quelltext steht "Wochenende". Normalerweise sollte nach der Umsetzung im Ausgabefeld "wo4ccde" stehen. Leider passiert aber nichts. Es erscheint auch keine Fehlermeldung.

    Die Funktionsdeklaration lautet:

    Public Declare Function lou_translateString Lib "d:\programmierung\punktbilder\braille\LibLouis.dll" _
    (ByRef tableList As String, ByRef inbuf As String, ByVal inlen As Long, _
    ByRef outbuf As String, ByRef outlen As Long, ByRef typeform As Byte, _
    ByRef spacing As Long, mode As Long) As Long

    Die Aufrufende Funktion sieht nun so aus:

    Private Sub UebersetzenBefehl_Click()
    lou_translateString "d:\Programmierung\PunktBilder\Braille\Brailletabellen\de-de-g2.ctb", Text1Text, Len(Text1Text), Text2Text, Len(Text1Text), 0, 0, 1
    End Sub

    Ich bin für eure Tipps sehr dankbar.
    Du kannst für die Ausgabelänge nicht Len(...) übergeben. Aus diesem Parameter wird etwas zurückgeschrieben, aber in den Rückgabewert einer Funktion kann man nichts schreiben.
    Und woher kommen jetzt die ganzen ByRefs? Die brauchst du nur da, wo ich sie auch hingesetzt hab.
    Ich bekomme leider immer noch kein brauchbares Ergebnis. Heute habe ich mir aus der gleichen DLL eine einfachere Funktion vorgenommen:

    char *lou_version ()

    This function returns a pointer to a character string containing the
    version of liblouis, plus other information, such as the release date
    and perhaps notable changes.

    In VB habe ich folgende Deklaration gemacht:

    Public Declare Function lou_version Lib "D:\programmierung\punktbilder\braille\LibLouis.dll" () As String

    Aufgerufen wird die Funktion folgendermaßen:

    Text2Text = lou_version

    Leider bekomme ich auch hier kein Ergebnis. Wie kann man in VB6 einen C-String anhand eines zurückgegebenen Pointers auslesen?