Announcement

Collapse
No announcement yet.

Delphi4.0-Klassen in C# nutzen

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

  • Delphi4.0-Klassen in C# nutzen

    Hallo,<BR>ist es möglich in Delphi4.0 geschriebene Klassen in C# zu nutzen (über Dll)?<BR>MfG<BR>Jürgen

  • #2
    Als Klasse nicht.

    Aber wenn Du dir ein Funktionsinterface dafür erstellst und diese DLL-Funktionen entsprechend C#-Syntax einbindest schon.
    Für jede Methode die du von der Klasse verwenden willst lege ein DLL-Funktion an. Wenn du die Klasse in mehreren Instanzen verwenden willst mußt Du als ersten Parameter noch einen Handle-parameter definieren der die Instanz der Klasse bestimmt.

    Die 2te Möglichkeit wäre über COM zu gehen. Erstellen eine COM-Wrapper und binde diesen dann in C# ein.

    Ich würde die erste Methode bevorzugen, da dur die COM-Probleme (Registrierung, Versionsproblem) sparst

    Comment


    • #3
      Hallo Bernhard,<BR>danke für deine schnelle Antwort, hättest Du vielleicht ein kleines Code-Beispiel auf Lager?<BR>Die erste Idee scheint mir auch die Bbessere zu sein. Ich würde das ganze Spektum einer Klasse nutzen wollen (Eigenschaften, Methoden und ganz wichtig Ereignisse).<BR>Wäre nett, wenn du mir auch dort helfen könntest.<BR>Danke in Voraus!<BR>MfG<BR>Jürge

      Comment


      • #4
        Hallo Jürgen,

        leider hab ich dafür kein Code-Beispiel auf Lager. Das Prinzip kenn ich nur aus einem C++-Programm aus meiner alten Arbeitsstelle. Und das ist auch schon ca 4 Jahre her ..

        Comment


        • #5
          Hallo,

          wenn die "alte" DLL-Schnittstelle über <i>P/Invoke</i> bedient werden soll, muss die eigene Delphi-DLL für jede Funktion eine so genannten Schnittstellenprozedur (siehe Delphi-Hilfe) deklarieren und exportieren. Allerdings kann auf diesem Weg keine Klasseninstanz übertragen werden.

          Der einzige "saubere" Weg besteht darin, die Delphi-Klasse über ein Automation-Objekt (COM) zu verpacken, und von .NET aus diese Umverpackung über <i>COM Interop</i> zu nutzen. Nur so lassen sich auch Ereignisse (Events) in Richtung .NET transportieren. Eine Schnittstellen-Prozedur (reine DLL-Schnittstelle ohne COM) kann so etwas nicht leisten.

          In einem praktischen Beispiel sieht das dann so aus (ein C#-Client greift auf ein Delphi 6-Automationobjekt zu, das Events auslöst). Die eigene Hilfsklasse <i>AdressverwaltungEventsHelperClass</i> implementiert das Interface IAutObjEvents des Automation-Objekts, um dort gleich 2 Aufgaben zu erfüllen: <br>
          1. Nutzfunktion der Events von IAutObjEvents <br>
          2. Kontrollieren der Lebensdauer der Interface-Zeiger

          <pre>
          <b>using</b> System;
          <b>using</b> System.Runtime.InteropServices;
          <b>using</b> System.Windows.Forms;

          <b>namespace</b> AdressverwaltungCSClient
          {
          <font color="#003399"><i>/// &lt;summary&gt;</i></font>
          <font color="#003399"><i>/// Hilfsklasse kapselt die Events der Adressverwaltung ein</i></font>
          <font color="#003399"><i>/// &lt;/summary&gt;</i></font>
          <b>public</b> <b>class</b> AdressverwaltungEventsHelperClass: Adressverwaltung.IAutObjEvents
          {
          <b>private</b> Form1 aMainForm;
          <b>private</b> UCOMIConnectionPoint icp;
          <b>private</b> UCOMIConnectionPointContainer icpc;
          <b>private</b> <b>int</b> cookie;

          <font color="#003399"><i>/// &lt;summary&gt;</i></font>
          <font color="#003399"><i>/// Default-Konstruktor (ohne eigene Funktion)</i></font>
          <font color="#003399"><i>/// &lt;/summary&gt;</i></font>
          <b>public</b> AdressverwaltungEventsHelperClass()
          {
          }

          <font color="#003399"><i>/// &lt;summary&gt;</i></font>
          <font color="#003399"><i>/// Überladener Konstruktor legt Verweis auf das Hauptformular in einem</i></font>
          <font color="#003399"><i>/// eigenen Objektfeld (aMainForm) ab und baut dann die Verbindung zur</i></font>
          <font color="#003399"><i>/// ConnectionPoint-Schnittstelle von COM auf.</i></font>
          <font color="#003399"><i>/// &lt;/summary&gt;</i></font>
          <font color="#003399"><i>/// &lt;param name=&quot;aForm&quot;&gt;&lt;/param&gt;</i></font>
          <b>public</b> AdressverwaltungEventsHelperClass(Form1 aForm)
          {
          aMainForm = aForm;
          icpc = (UCOMIConnectionPointContainer)aMainForm.aObj;
          Guid IID_IMyEvents = <b>typeof</b>(Adressverwaltung.IAutObjEvents).GUID;
          icpc.FindConnectionPoint(<b>ref</b> IID_IMyEvents,<b>out</b> icp);
          icp.Advise(<b>this</b>,<b>out</b> cookie);
          }

          <font color="#003399"><i>/// &lt;summary&gt;</i></font>
          <font color="#003399"><i>/// Der Anwender hat in der Adressverwaltung auf den Button »Weiter« geklickt,</i></font>
          <font color="#003399"><i>/// die Kundendaten liegen somit vor, die Verbindung zur Adressverwaltung </i></font>
          <font color="#003399"><i>/// kann abgebaut werden. Dazu ruft das Programm die Interface-Methode »pQuit«</i></font>
          <font color="#003399"><i>/// des Automations-Objekts (nicht des Events-Objekts!) auf.</i></font>
          <font color="#003399"><i>/// &lt;/summary&gt;</i></font>
          <font color="#003399"><i>/// &lt;param name=&quot;vAdrId&quot;&gt; &lt;description&gt;Adress-ID des Kunden &lt;/description&gt;&lt;/param&gt;</i></font>
          <font color="#003399"><i>/// &lt;param name=&quot;vAdrAend&quot;&gt;&lt;/param&gt;</i></font>
          <font color="#003399"><i>/// &lt;param name=&quot;vVersNr&quot;&gt;&lt;/param&gt;</i></font>
          <b>public</b> <b>void</b> OnNext(<b>object</b> vAdrId, <b>object</b> vAdrAend, <b>object</b> vVersNr)
          {
          aMainForm.DoSetData(vAdrId.ToString(), vAdrAend.ToString());
          aMainForm.aObj.pQuit();
          }

          <font color="#003399"><i>/// &lt;summary&gt;</i></font>
          <font color="#003399"><i>/// Benutzer hat den Abbrechen-Button in der Adressverwaltung angeklickt, damit </i></font>
          <font color="#003399"><i>/// das Programmfenster der Adressverwaltung ohne Warnhinweis verschwindet, muss</i></font>
          <font color="#003399"><i>/// der &quot;offizielle&quot; Weg des Verbindungsabbaus beschritten werden. Das eigene</i></font>
          <font color="#003399"><i>/// Programm ruft dazu die Interface-Methode »pQuit« des Automations-Objekts auf. </i></font>
          <font color="#003399"><i>/// &lt;/summary&gt;</i></font>
          <b>public</b> <b>void</b> OnAbort()
          {
          aMainForm.aObj.pQuit();
          }

          <font color="#003399"><i>/// &lt;summary&gt;</i></font>
          <font color="#003399"><i>/// Das Event-Objekt der Adressverwaltung kündigt das Programmende an, das eigene</i></font>
          <font color="#003399"><i>/// Programm muss alle aktiven Interface-Zeiger freigeben, damit Windows für die</i></font>
          <font color="#003399"><i>/// Adressverwaltung nicht den Warnhinweis für die noch offenen COM-Verbindungen</i></font>
          <font color="#003399"><i>/// anzeigt. </i></font>
          <font color="#003399"><i>/// &lt;/summary&gt;</i></font>
          <b>public</b> <b>void</b> OnQuit()
          {
          icp.Unadvise(cookie);
          <font color="#003399"><i>// 1. Interface </i></font>
          <b>while</b> (Marshal.ReleaseComObject(icp) &gt; 0)
          ;
          icp = <b>null</b>;
          <font color="#003399"><i>// 2. Interface</i></font>
          <b>while</b> (Marshal.ReleaseComObject(icpc) &gt; 0)
          ;
          icpc = <b>null</b>;
          }
          }
          }
          </pre>
          Aufruf im C#-Programm:
          <pre>
          <b>public</b> Adressverwaltung.AutObjClass aObj;
          <b>public</b> <b>void</b> DoSetData(<b>string</b> sAdr_id, <b>string</b> sDatum)
          {
          label1.Text = sDatum;
          label2.Text = sAdr_id;
          }
          <b>private</b> <b>void</b> buttonStartSinkContainer_Click(<b>object</b> sender, System.EventArgs e)
          {
          aObj = <b>new</b> Adressverwaltung.AutObjClass();
          AdressverwaltungEventsHelperClass aSinkHelper = <b>new</b> AdressverwaltungEventsHelperClass(<b>this</b>);
          aObj.fStart(0,<b>null</b>);
          }
          </pre&gt

          Comment


          • #6
            Hallo,<BR>Allen erstmal vielen Dank,<BR>ich werde mich jetzt hinsetzen um die Sachen auszuprobieren.<BR>MfG<BR>Jürge

            Comment

            Working...
            X