Announcement

Collapse
No announcement yet.

D8 und DLL's Exports

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

  • D8 und DLL's Exports

    Hallo,

    ich habe einige D6-DLL's die Funktionalität in Form von Callbacks an übergeordnete Programme exportieren.
    Bsp.:
    <PRE>
    procedure On_Start(MyInstance:Longword; MyWnd:Longword; Avtive:BOOL ; MyDLL_ID :integer);cdecl;
    procedure My_Proc( MyID : integer; MyLength :integer; var MyData);cdecl;

    exports On_Start name 'On_Start';

    implementation

    procedure On_Start(MyInstance:Longword; MyWnd:Longword; Avtive:BOOL ; MyDLL_ID :integer);cdecl;
    var i:integer;
    begin
    _MyInstance:=MyInstance;
    _MyWindow:=MyWnd;
    _MyDLL_ID:=MyDLL_ID;
    SendMessage(_MyWindow,WM_USER,MY_CALLBACK,(LongWor d(@MyProc)));
    end;

    procedure My_Proc( MyID : integer; MyLength :integer; var MyData);cdecl;
    var Buffer: PByteArray;
    begin
    Buffer:=@MyData;
    // Do my datahandling
    // .................
    end;
    </PRE>

    Wird das in dieser Form problemlos unter D8 laufen ? Was mir noch nicht klar ist, ist wie die entsprechenden Exports an das übergeordnete Programm übergeben wird. Denn da ist ja nun das DOT.NET Framework "dazwischen".
    Vielleicht hat jemand 'nen Link wo ich mich ein wenig dazu einlesen kann.

    Gruss
    stalle

  • #2
    Hallo,

    &gt;Wird das in dieser Form problemlos unter D8 laufen ?

    Was Callbacks angeht ja - auch Delphi 8 kann Win32-Callback-Funktionen abarbeiten. Das folgende Beispiel für die Win32-API-Funktion <b>EnumWindows</b> demonstriert dies - der Adress-Operator <b>@</b> liefert die Adresse der Methode zurück, die an die Win32-API-Funktion <i>EnumWindows</i> übergeben wird :
    <pre>
    <b>uses</b>
    System.Drawing, System.Collections, System.ComponentModel,
    System.Windows.Forms, System.Data, Windows, System.Text;

    <b>type</b>
    TWinForm = <b>class</b>(System.Windows.Forms.Form)
    <font color="#003399"><i>{$REGION 'Designer Managed Code'}</i></font>
    ...
    <font color="#003399"><i>{$ENDREGION}</i></font>
    strict <b>protected</b>
    <b>procedure</b> Dispose(Disposing: Boolean); <b>override</b>;
    <b>private</b>
    <b>function</b> DoEnumWindowNamesCallback(aHandle: HWND; aParam: LPARAM): BOOL;
    <b>public</b>
    <b>constructor</b> Create;
    <b>end</b>;

    ...

    <b>function</b> TWinForm.DoEnumWindowNamesCallback(aHandle: HWND; aParam: LPARAM): BOOL;
    <b>var</b>
    aSB : StringBuilder;
    <b>begin</b>
    aSB := StringBuilder.Create;
    aSB.Append(<font color="#9933CC">' '</font>, 254);
    GetWindowText(aHandle, aSB, 254);
    <b>if</b> aSB.ToString &lt;&gt; <font color="#9933CC">''</font> <b>then</b>
    ListBox1.Items.Add(aSB.ToString);
    Result := True;
    <b>end</b>;

    <b>procedure</b> TWinForm.ButtonEnumWindows_Click(sender: System.<b>Object</b>; e: System.EventArgs);
    <b>begin</b>
    EnumWindows(@DoEnumWindowNamesCallback, 0);
    <b>end</b>;
    </pre>
    &gt;..Denn da ist ja nun das DOT.NET Framework "dazwischen"...

    Das magische Zauberwort nennt sich <b>P/Invoke</b> (alias <i>Platform Invocation Services</i>). Über das <b>MarshalAs</b>-Attribut kann die von der DLL erwartete Datenstruktur sowie die Interpretation durch das .NET Framework exakt beschrieben werden. Als Beispiel könnte das dann so aussehen, wenn eine mit Delphi 7 compilierte DLL eingebunden werden soll (dieses Beispiel demonstriert im Fall eines nullterminierten Strings den "umständlichen" Weg und könnte auch einfacher umgesetzt werden):
    <pre>
    [DllImport(<font color="#9933CC">'RedSys2NETWin32.dll'</font>, CharSet = CharSet.Ansi,SetLastError = False, EntryPoint = <font color="#9933CC">'OSDocSummarayCharCount'</font>)]
    <b>function</b> OSDocSummarayCharCount([MarshalAs(UnmanagedType.LPStr)]sDoc: System.<b>String</b>): Integer; <b>external</b>;
    </pre&gt

    Comment

    Working...
    X