Announcement

Collapse
No announcement yet.

Interface-DLL (VB.NET <-> Delphi 7) - Übergabe fehlerhaft.

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

  • Interface-DLL (VB.NET <-> Delphi 7) - Übergabe fehlerhaft.

    Hallo!

    Ich übergebe von VB.Net aus einige Variablen als <b>String</b> welche von meiner Delphi-Klasse als <b>PChar</b> erwartet werden. Bei der Übergabe scheint aber irgend etwas schief zu laufen, es kommt nur irgend welcher "Müll" an und immer ist eine Variable undefiniert, wodurch eine Objektverweis-Fehler auftritt.<br>
    Was habe ich übersehen/falsch gemacht?<br>
    <br>
    <i>Interface-Klasse in Delphi:</i>
    <pre>
    <font face=curier>library DMAPI;
    <font face=curier>
    <font face=curier>//<font face=curier>====================================== ========================================
    <font face=curier>
    <font face=curier>uses
    <font face=curier> SysUtils,
    <font face=curier> Classes,
    <font face=curier> Dialogs,
    <font face=curier> MAPI,
    <font face=curier> FNC; // enthält div. eigene Funktionen u.a. auch 'SendMail()' für MAPI

    <font face=curier>//================================================== ============================

    <font face=curier>function MAPISendMail(const ATitle, AMsg, ARecips, AFiles: PChar;
    <font face=curier> AStyle: Integer; Aply: Boolean): Boolean;
    <font face=curier>var
    <font face=curier> sDummy: String;
    <font face=curier> lRecips, lFiles: TStrings;
    <font face=curier> lStyle: TMAPIStyle;
    <font face=curier> nIdx: Integer;
    <font face=curier>begin
    <font face=curier> lRecips := TStringList.Create;
    <font face=curier> lFiles := TStringList.Create;

    <font face=curier> sDummy := '';
    <font face=curier> for nIdx := 0 to Length(ARecips) - 1 do
    <font face=curier> begin
    <font face=curier> if (ARecips[nIdx] = ';')
    <font face=curier> then begin
    <font face=curier> lRecips.Add(sDummy);
    <font face=curier> sDummy := '';
    <font face=curier> end
    <font face=curier> else begin
    <font face=curier> sDummy := sDummy + ARecips[nIdx];
    <font face=curier> end;
    <font face=curier> end;
    <font face=curier>
    <font face=curier> sDummy := '';
    <font face=curier> for nIdx := 0 to Length(AFiles) - 1 do
    <font face=curier> begin
    <font face=curier> if (AFiles[nIdx] = ';')
    <font face=curier> then begin
    <font face=curier> lFiles.Add(sDummy);
    <font face=curier> sDummy := '';
    <font face=curier> end
    <font face=curier> else begin
    <font face=curier> sDummy := sDummy + AFiles[nIdx];
    <font face=curier> end;
    <font face=curier> end;

    <font face=curier> case AStyle of
    <font face=curier> 0: lStyle := msLogon;
    <font face=curier> 1: lStyle := msDialog;
    <font face=curier> 2: lStyle := msHidden;
    <font face=curier> else lStyle := msDialog;
    <font face=curier> end;

    <font face=curier> Result := SendMail(ATitle, AMsg, lRecips, lFiles, <font face=curier>lStyle, Aply); // included in FNC (s.o.)
    <font face=curier>end;

    <font face=curier>//================================================== ============================

    <font face=curier>exports
    <font face=curier> MAPISendMail name 'DMAPI_SendMail';

    <font face=curier>end.</font></pre>
    <br>
    <i>Interface-Klasse in VB.NET:</i>
    <pre>
    <font face=curier>Imports System.Runtime.InteropServices

    <font face=curier>Public Class MAPI32_INTERFACE

    <font face=curier> <font color=grey>'function SendMail(const ATitle, AMsg: String; ARecips, AFiles: TStrings; AStyle: TMAPIStyle; Aply: Boolean): Boolean;</font>
    <font face=curier> <DllImport("DMAPI.dll", EntryPoint:="DMAPI_SendMail")> _
    <font face=curier> Public Shared Function MAPISendMail(ByVal ATitle As <font face=curier>String, ByVal AMsg As String, ByVal ARecips As String, _
    <font face=curier> ByVal AFiles As String, ByVal AStyle As Integer, ByVal <font face=curier>Aply As Boolean) As Boolean
    <font face=curier> ' bleibt Leer
    <font face=curier> End Function

    <font face=curier>End Class</font></pre>
    <br>
    <i>Verwendung in VB.NET</i>
    <pre>
    <font face=curier> Public Shared Function SendMail(ByVal ATitle As String, <font face=curier>ByVal AMsg As String, ByVal ARecips As IList, ByVal <font face=curier>AFiles As IList, ByVal AStyle As eMAPIStyle, ByVal Aply As <font face=curier>Boolean) As Boolean
    <font face=curier> Dim lRecips, lFiles As String
    <font face=curier> Dim lMAPI As xMAPI.MAPI32_INTERFACE

    <font face=curier> lRecips = ListToString(ARecips, ";")
    <font face=curier> lFiles = ListToString(AFiles, ";")

    <font face=curier> lMAPI = New xMAPI.MAPI32_INTERFACE
    <font face=curier> Return lMAPI.MAPISendMail(ATitle, AMsg, lRecips, <font face=curier>lFiles, CInt(AStyle), Aply) <font color=red><- Objektverweis wurde nicht auf eine Objektinstanz festgelegt</font>
    <font face=curier> End Function</font></pre>
    <br>

    Vielen Dank<br>
    Nico Stöckigt

  • #2
    Hallo,

    Eine über P/Invoke eingebundene Funktion dann direkt aufgerufen werden. Das Instanzieren der Klasse über New ist daher völlig unnötig (solang nicht die Methode zum Aufruf der P/Invoke-Funktion direkt dort implementiert wird)

    Comment


    • #3
      wo PChar erwartet wird immer eine StringBuilder übergeben.

      Gruß Henr

      Comment


      • #4
        Hallo!

        Ich habe den Quellcode jetzt folgendermaßen geändert und erhalte in meiner Zielklasse (in Delphi) dennoch nur <i>"Müll"</i>...<br>
        Die erste Variable beinhalten nur ein nicht darstellbares Zeichen, alle anderen sind leer bzw. nothing...

        <pre>-------------------8<--------------------
        Imports System.Text, System.Runtime.InteropServices
        </pre><pre>Public Class MAPI32_INTERFACE
        </pre><pre><font color="grey"> 'function SendMail(const ATitle, AMsg: String; ARecips, AFiles: TStrings; AStyle: TMAPIStyle; Aply: Boolean): Boolean;</font>
        <DllImport("DMAPI.dll", EntryPoint:="MAPISendMail")> _
        Public Shared Function MAPISendMail(ByVal ATitle As StringBuilder, ByVal AMsg As StringBuilder, _
        ByVal ARecips As StringBuilder, ByVal AFiles As StringBuilder, ByVal AStyle As Integer, _
        ByVal Aply As Boolean) As Boolean
        <font color="grey"> ' bleibt Leer </font>
        End Function
        </pre><pre>End Class
        -------------------8<--------------------</pre>
        <br>
        <pre>-------------------8<--------------------
        Public Shared Function SendMail(ByVal ATitle As String, ByVal AMsg As String, ByVal ARecips As IList, ByVal AFiles As IList, ByVal AStyle As eMAPIStyle, ByVal Aply As Boolean) As Boolean
        Dim lTitle, lMsg, lRecips, lFiles As StringBuilder
        Dim lMAPI As xMAPI.MAPI32_INTERFACE
        </pre><pre> lTitle = New StringBuilder
        lMsg = New StringBuilder
        lRecips = New StringBuilder
        lFiles = New StringBuilder
        </pre><pre> lTitle.Append(ATitle)
        lMsg.Append(AMsg)
        lRecips.Append(Convert.List2Str(ARecips, ";"))
        lFiles.Append(Convert.List2Str(AFiles, ";"))
        </pre><pre> Try
        lMAPI = New xMAPI.MAPI32_INTERFACE
        Return lMAPI.MAPISendMail(lTitle, lMsg, lRecips, lFiles, CInt(AStyle), Aply)
        Catch ex As Exception
        Debug.Write("'additional': SendMail -> " & ex.Message)
        Return False
        End Try
        End Function
        -------------------8<--------------------</pre>
        <br>
        Irgendwer noch eine Idee ?!?<br>
        <br>
        Vielen Dank!<br&gt

        Comment


        • #5
          Ok! mal wieder selbst verarscht!!!

          In der Delphi-DLL fehlte ein kleines aber wichtiges Wörtchen: <font face="courier new"><b> stdcall;</b></font> so das das ganze lauten muß:<pre>function MAPISendMail(const ATitle, AMsg, ARecips, AFiles: PChar;
          AStyle: Integer; Aply: Boolean): Boolean;<b> stdcall;</b>
          [...]</pre>
          Danke an Alle die mir bei der Suche geholfen haben!<br>
          <br>
          Gruß Nico Stöckigt<br&gt

          Comment

          Working...
          X