Announcement

Collapse
No announcement yet.

Delphi DLL in VB mit String Parameter

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Delphi DLL in VB mit String Parameter

    Hallo,

    für jemand der kein Rookie ist wie ich sicher kein Problem. Bitte um eure Hilfe.

    Habe eine Delphi(6.0)-DLL und möchte diese mit VB aufrufen und einen String übergeben. In Delphi hab ich aber dann immer Datenmüll im Parameter.
    Habe dazu schon paar Einträge hier gefunden, aber irgendwas mach ich immer noch falsch. Tatsache ist, ich muss einen string übergeben. Wie bringe ich Delphi dazu das er diesen versteht?

    VB-MODUL:
    Private Declare Function DUMMY Lib "BLABLA" (sDir As String) As Integer
    Private Sub Command1_Click()
    Dim iRet As Integer
    iRet = DUMMY("Hello World!")
    MsgBox CStr(iRet)
    End Sub

    DELPHI:
    library BLABLA;
    uses
    SysUtils,
    Windows,
    Classes;
    {$R *.res}
    Function DUMMY(sDirectory: Pchar):integer; stdcall;
    begin
    Messagebox(0,sDirectory,pchar('BLABLA'),0);
    DUMMY:=2;
    end;
    exports
    DUMMY;
    begin
    end.

  • #2
    IMHO verwendet Visual Basic WideString (COM BSTR) und nicht P(Ansi)Char.

    - nic

    Comment


    • #3
      Hallo,
      auch wenn ich den Parameter als widestring definiere bekomm ich nur Datenmüll in meine DLL übergeben.

      Function BLABLA(sDirectory: WideString):integer; stdcall;
      begin
      Messagebox(0,pchar(sDirectory),pchar('DUMMY'),0);
      BLABLA:=2;
      end;

      Bitte um Hilfe oder ein Beispiel das funktioniert.
      Vielen Dank

      Comment


      • #4
        Hallo,

        die von einer Delphi-DLL exportierten Funktionen werden mus der Aufrufkonvention <b>stdcall</b> gekennzeichnet, außerdem dürfen Strings nur als <b>PChar</b> (nullterminierte Windows-Strings) verwendet werden.
        <pre>
        library DelphiVBA;

        uses
        SysUtils, Classes, Windows;

        {$R *.RES}

        resourcestring
        cFmt = 'Word: %d; PChar: %s; DWORD%d; var TDataTime: %s; var DWORD: %d';

        function TestDLL(dWord : WORD; pPChar: PChar; dwDWORD: DWORD;
        var dtDateTime: TDateTime;
        var dwVarDWORD: DWORD): Integer; stdcall;
        begin
        MessageBox(0, PChar(Format(cFmt, [dWord, pPChar, dwDWORD,
        DateTimeToStr(dtDateTime), dwVarDWORD])),
        'Parameter-Test', 0);
        Result := 1;
        end;

        exports
        TestDLL;

        begin
        end.
        </pre>
        VB übergibt Parameter in der Voreinstellung als Referenz (Verweis auf die Variable), während Delphi im Gegensatz dazu Parameter in der Voreinstellung als Wert übergibt. Immer dann, wenn in Delphi kein <b>var</b>-Kennzeichner verwendet wird, muss in VBA die Deklaration über <b>ByVal</b> verwendet werden. Außerdem ist Integer in VBA noch immer 16-Bit, daher muss Long als Datentyp verwendet werden, wenn ein Delphi-Integer übergeben wird.
        <pre>
        Declare Function TestDLL Lib "E:\Ablage\DelphiVBA.DLL" _
        (ByVal dWord As Integer, _
        ByVal pPChar As String, _
        ByVal dwDWORD As Long, _
        dtDateTime As Date, _
        dwVarDWORD As Long) As Long

        Sub DelphiVBA()

        Dim dtDate
        Dim dwVDWORD

        dtDate = "09.02.2001"
        dwVDWORD = 123
        iReturn = TestDLL(11, "Das ist ein Test", 12, dtDate, dwVDWORD)
        MsgBox iReturn

        End Sub
        </pre>
        P.S: Generell hat Nico natürlich Recht, was an BSTR angeht. Aber der Aufwand über <i>CoTaskMemAlloc</i> etc. ist dann doch zu hoch, so dass der "vorsichtige" PChar-Einsatz die bessere Alternative ist (zumal diese problemlos auch mit VB.NET funktioniert)

        Comment


        • #5
          Vielen Dank für die Erklärung. Funktioniert nun einwandfrei.

          Jetzt noch ein kleines Problem.

          Möchte nun einen String als Rückgabeparameter deklarieren.
          in VB:
          Public Declare Function Archive Lib "DNArchiveLink" (ByVal sFN As String, ByRef sDocID As String) As Long

          Daher müsste doch die Delphi-Funktion so deklariert werden:
          function Archive(sFN: PChar; out sDocID: PChar):integer; export; stdcall;

          Funktioniert soweit auch, bekomme aber immer nur die ersten 8 Zeichen zurück. Lege einen Buffer an und übergebe diesen:
          Aufruf in VB mache ich wie folgt:

          Dim sDocID As String
          Dim sRet As Integer
          sDocID = Space(80)
          sRet = Archive("c:\test.tif", sDocID)

          Schätze der Fehler liegt in der Delphi-Funktion, oder

          Comment

          Working...
          X