Announcement

Collapse
No announcement yet.

Wege der COM/Interface Nutzung

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

  • Wege der COM/Interface Nutzung

    Hi Leute

    Ich mache mir zur Zeit Gedanken wie ich die Interfaces am cleversten nutzen kann und was wohl der beste Kompromiss zwischen Design, Portabilität und Flexibilität ist. Ich möchte nicht auf die Windows COM Schiene mit IDispatch usw. Möchte aber das es unter umständen sehr leicht ist meine Interfaces auch aus anderen Sprachen, z.B. BCB, oder aus DLL's heraus zu nutzen. z.B.

    <pre>

    type
    ISmallPrimes = interface
    ['{126BE100-061D-4067-9E0A-E2A490AF5CEA}']
    function GetPrime(Index: cardinal): Cardinal; stdcall;

    property Prime[Index: Cardinal]: Cardinal read GetPrime; default;
    end; <br>

    function Primes: ISmallPrimes; stdcall; <br>

    </pre>

    D.h. im Falle der Nutzung aus DLL's oder anderen Sprachen muß diese die Interface-Deklaration importieren und die jeweilige function Primes.

    Nun tauchen aber wichtige Fragen auf
    <li>welche Calling-Konvention sollte benutzt werden ?
    <li>welche Datentypen (Integer, Cardinal usw.) sollte preferiert werden ?
    <li>welche Datentypen sollten NICHT verwendet werden ?
    <li>welchen Datentyp für Strings ? vollständig vermeiden ?
    <li>wie mit komplexen Strukturen arbeiten ?
    <li>wie allozierte Speicherparameter übergeben, nutzen ?
    <li>wie werden Variants vermieden ?
    <li>in wie weit erreicht man die höchste, spätere, Kompatibilität ohne den Overhead von COM,ActiveX und ohne viel vom PASCAL Objectdesign abzuweichen ?
    <li>wichtig ist die Kylix Kompatibilität !<br>

    Grundsätzlich bieten die Interfaces mit dem Referencecounting einen sehr komfortablen Weg der Speicher/Lifetimeverwaltung, diesen Vorzug will ich nutzen.<br>
    Generell würden mir Allozierungs-Funktionen wie oben gezeigt völlig ausreichen. Auf jeden Fall müsste man dann die Verwendung von Delphi Objecten verweiden, ich meine als User-Interface, also nur intern in der mplementierung.<br>

    Andreas, Du als Experte, kannst mich bestimmt aufklären.<br>

    Gruß Hagen

  • #2
    Hallo Hagen,

    &gt;Ich möchte nicht auf die Windows COM Schiene mit IDispatch

    hinter IDispatch verbirgt sich die Visual Basic-Schiene (denn dieses Interface wurde erst nachgerüstet, damit VB mit COM hantieren kann). Das Betriebssystem selbst verwendet die VTable-Interfaces und greift über Zeiger darauf zu.

    Es stellt sich die Frage, ob sich das Ganze lohnt. Der Worst Case-Fall (je nach Standpunkt) würde so aussehen: <br>
    - Microsoft .NET setzt sich in der Windows-Welt durch <br>
    - Projekt MONO (.NET für Linux) steht in der Linux-Welt zur Verfügung <br>
    - Borland setzt die Delphi-Kylix-Kompatiblität dadurch um, indem beide auf .NET aufsetzen (in diesem Fall machen Dritte fast die ganze Arbeit, und Borland könnte als Trittbrettfahrer so wie alle anderen .NET-Sprachen auch auf die CLR und das Framework zurückgreifen). Es ist doch letztendlich egal, ob die Delphi-Kylix-Kompatibilität durch eine externe C++-Klassenbibliothek (wie es Heute mit der CLX der Fall ist) oder durch .NET erreicht wird. Wobei .NET für Borland sogar in zweifacher Hinsicht preiswerter wäre (zum einen fallen im Gegensatz zur CLX für Borland keine Lizenzkosten für den Einsatz unter Windows an und zum anderen ist dann auch der interne Entwicklungsaufwand für Borland niedriger, da CLR und Framework von Dritter Seite bereitgestellt werden).

    Solange Borland nicht dazu Stellung genommen hat, wie man auf .NET reagieren will, besteht die Gefahr, mit eigenen neuen Projekten in eine Sackgasse zu geraten. Mit .NET würde alles bereits zur Verfügung stehen, so dass nicht nichts gibt, was man an dieser Stelle selbst nachrüsten müsste

    Comment


    • #3
      Hi Andreas

      Deshalb meine Fragen. Ich nehme an das ich so oder so Pascal Objecte weiterhin nutzen werde. Die paar Zeilen Code um ein IInterface zu definieren stören da nicht sehr. Die Frage ist und bleibt aber, was sind die besten Datentypen und welche sollte man vermeiden ?

      Gruß Hage

      Comment


      • #4
        Hallo Hagen,

        &gt;Was sind die besten Datentypen und welche sollte man vermeiden?

        a) Idealfall: .NET-Datentypen der CLR<br>
        - sbyte 8-Bit-Integer mit Vorzeichen (signed) <br>
        - byte 8-Bit-Integer ohne Vorzeichen <br>
        - short 16-Bit-Integer mit Vorzeichen <br>
        - ushort 16-Bit-Integer ohne Vorzeichen <br>
        - int 32-Bit-Integer mit Vorzeichen <br>
        - uint 32-Bit-Integer ohne Vorzeichen <br>
        - long 64-Bit-Integer mit Vorzeichen <br>
        - ulong 64-Bit-Integer ohne Vorzeichen <br>
        - char 16-Bit-Integer ohne Vorzeichen (Unicode) <br>
        - float 32-Bit-Fließkommazahl <br>
        - double 64-Bit-Fließkommazahl <br>
        - bool<br>
        - decimal 128-Bit-Fließkommazahl (Ganzzahl-Interpretation) <br>
        - string (Unicode) <br>

        b) Interoperationalitäts-Kompromiss: <br>
        Automation-kompatible Datentypen, damit der gegenseitige Zugriff auf und von .NET über den Runtime Callable Wrapper (RCW) bzw. COM Callable Wrapper (CCW) genutzt werden kann.

        Die Aufrufkonvention stdcall ist eine gute Wahl

        Comment


        • #5
          Ok, die generischen Type sind nicht das Problem.<br>

          Was kann ich tun wenn Strings, allozierte Speicher etc. benutzt werden müssen ?<br>

          Wäre ein Interface zum speicherzugriff wie z.B. IStream, IPersistent eine Idee ?<br>

          Gruß Hage

          Comment


          • #6
            Hallo Hagen,

            für COM (alles spielt sich unter Win32 ab) ist es einfach, da <i>CoTaskMemAlloc</i> (alias SHGetMalloc alias CoGetMalloc) als gemeinsamer Speicher-Manager zur Verfügung steht, so dass ein COM-Objekt einen Speicherbereich anfordern kann, den ein anderes Objekt wieder freigibt. Wenn das aber sowohl unter Delphi als auch unter Kylix laufen soll, wird es kompliziert. Man müsste eine DLL (SO) bereitstellen, die ein mit IMalloc vergleichbares Interface liefert und die für das Anfordern/Freigeben von Speicherbereichen zuständig ist.
            <pre>
            IMalloc = interface(IUnknown)
            ['{00000002-0000-0000-C000-000000000046}']
            function Alloc(cb: Longint): Pointer; stdcall;
            function Realloc(pv: Pointer; cb: Longint): Pointer; stdcall;
            procedure Free(pv: Pointer); stdcall;
            function GetSize(pv: Pointer): Longint; stdcall;
            function DidAlloc(pv: Pointer): Integer; stdcall;
            procedure HeapMinimize; stdcall;
            end;
            </pre>
            Das IStream-Interface setzt über die Win32-API-Funktion CreateStreamOnHGlobal ebenfalls nur auf den gemeinsamen Speicher-Manager von Win32 auf. Für Kylix wird das wieder zum Problem, solange man kein Gegenstück zu IMalloc hat

            Comment

            Working...
            X