Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Objekt in einer DLL kapseln (https://www.delphipraxis.net/90814-objekt-einer-dll-kapseln.html)

DelphiManiac 24. Apr 2007 10:56


Objekt in einer DLL kapseln
 
Hallo,

ich habe zurzeit folgendes Problem:

Ich habe eine Unit, nennen wir sie mal Geraet_API
In ihr habe ich eine Klasse zur Steuerung und Konfiguration eines Geraetes.

Sieht dann ungefähr so aus:

Delphi-Quellcode:
TGeraet.Set_GeraeteReset; // Setzt das Gerät zurück
TGeraet.Set_Seriennummer(SN:String); // speichert die Seriennummer im Gerät ab
...
Mein Problem ist nun, ich will diese Funktionen der API auslagern in eine DLL.

Wie kann ich denn in meiner DLL ein Objekt erzeugen um den Zugriff der DLL zu ermöglichen?

Danke euch!

Robert Marquardt 24. Apr 2007 11:07

Re: Objekt in einer DLL kapseln
 
Ein Objekt in einer DLL zu instantiieren ist problemlos. Man muss es halt nur explizit machen.
Probleme treten erst auf wenn man das Objekt an das Hauptprogramm gibt. DLL und Hauptprogramm haben separate Memorypools. Die Einbindung von ShareMem beseitigt diese Probleme.
Eine DLL die direkt eine Klasse implementiert ist nur in C++ moeglich und verstoesst gegen Sinn und Zweck einer DLL. Die Klassenimplementation ist naemlich Compilerspezifisch.

DelphiManiac 24. Apr 2007 11:11

Re: Objekt in einer DLL kapseln
 
Hallo,

eigentlich will ich gar nicht ein Objekt übergeben, will es nur für meine Exportierung der Funktionen nutzten.
D.h. ich will ja nicht meine ganzen Methoden in Klassen umschreiben müssen.

Wie mache ich das denn am Besten?

Luckie 24. Apr 2007 11:13

Re: Objekt in einer DLL kapseln
 
Klassen und DLLs sind nicht wirklich eine sinnvolle und glückliche Kombination und sollte möglichst vermieden werden. Gründe findest du hier im Forum. Für Delphi böten sich noch Packages an, welches eigentlich nur Delphi spezifische DLLs sind.

DelphiManiac 24. Apr 2007 11:16

Re: Objekt in einer DLL kapseln
 
Hallo Luckie,

ja bpls kann ich leider nicht nutzen, da ich die DLL von Visual Basic-Programmierern (aaah) genutzt werden soll :shock:
Mmh, heißt das im Umkehrschluss ich muss meine Unit so umschreiben, dass ich nur Funktionen ohne Klassenimplemenation habe?

Gruß
DelphiManiac

Robert Marquardt 24. Apr 2007 11:18

Re: Objekt in einer DLL kapseln
 
Ein zur DLL internes Objekt ist wirklich problemlos. Wenn das DLL API sauber sprachunabhaengig ist (also keine Delphi Strings usw), dann instantiiere einfach das Objekt.

Elvis 24. Apr 2007 11:22

Re: Objekt in einer DLL kapseln
 
Verpacke deine Klasse in ein Interface und sorge dafür, dass die Verwendung aller Eigenschaften und Parameter unabhängig vom Memorymanager sind.
Zum Beispiel WideString statt AnsiString.
Nun brauchst du nur noch eine exportierte Funktion, die dir die Interface-Referenz zurückgibt.
Nachtrag:
Zitat:

Zitat von DelphiManiac
ja bpls kann ich leider nicht nutzen, da ich die DLL von Visual Basic-Programmieren (aaah) genutzt werden soll :shock:

lol, vergiss es einfach, wenn dir deine geistige Gesundheit am Herzen liegt. :lol:
Wenn nicht:
Was du hier machen müsstest wäre eine ActiveX-Library.
Die Stubs für deine COM-Klasse lässt sich dann im TypeLib-Editor anlegen, er generiert für dich dann auch das COM-Interface und ein Dispatch-interface.
Ob du dir wirklich VB-*piep*s als Benutzer deiner Lib aufhalsen willst ist deine Entscheidung, und das dürfte auch schon der schwierigste Teil des Ganzen sein. ;)

DelphiManiac 24. Apr 2007 11:22

Re: Objekt in einer DLL kapseln
 
@Robert Marquardt

Wo genau soll ich denn das Objekt erzeugen
Delphi-Quellcode:
library DLL;

{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der
  ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt-
  Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die
  Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle
  Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die
  sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur
  Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL.
  Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String-
  Informationen als PChar- oder ShortString-Parameter übergeben. }
 

uses
  SysUtils,
  Classes;
exports
 // kann ich dann sowas machen??
 Obj.Set_Seriennummer;//????

begin
// HIER????
Obj:=TGeraet.Create;//??
end

DelphiManiac 24. Apr 2007 11:24

Re: Objekt in einer DLL kapseln
 
Dass mit den VB'lern kann ich mir leider nicht aussuchen ... :stupid:

Robert Marquardt 24. Apr 2007 11:31

Re: Objekt in einer DLL kapseln
 
Exportieren kann man nur einfache Funktionen. Du musst also ein Funktions-API stricken. Das sollte einfach sein, da du ja nur genau ein Objekt in einer globalen Variablen hast.

Delphi-Quellcode:
library DLL;

uses
  SysUtils,
  Classes;

var
  Geraet: TGeraet;

function Seriennummer: Cardinal;
begin
  Result := Geraet.Seriennummer;
end;

// wie man das Objekt beim Entladen der DLL brav freigibt

procedure LibExit(Reason: Integer);
begin
  if Reason = DLL_PROCESS_DETACH then
    FreeAndNil(Geraet);
end;

exports
  Seriennummer;

begin
  DLLProc := LibExit;
  Geraet := TGeraet.Create;
end

Bernhard Geyer 24. Apr 2007 11:35

Re: Objekt in einer DLL kapseln
 
Zitat:

Zitat von DelphiManiac
ja bpls kann ich leider nicht nutzen, da ich die DLL von Visual Basic-Programmierern (aaah) genutzt werden soll :shock:

VB? Dann erstell doch ein Automatisierungsobjekt. Das diese DLL dann registriert werden muß ist doch für VB (Nicht VB.NET)-Entwickler eh das normalste der Welt.

DelphiManiac 24. Apr 2007 11:45

Re: Objekt in einer DLL kapseln
 
@Robert Marquardt

Super Klasse!!

Genau so klappts (zumindest meine erste Methode :-))

Also kann ich den Methodenaufruf in einer normalen Funktion kapseln und diese veröffentlichen, so nutze ich intern das Objekt,
das aber extern vollkommen uninteressant ist.

Danke dir nochmal

@Bernhard Geyer:

Was meinst du genau mit Automatisierungsobjekt??

Bernhard Geyer 24. Apr 2007 12:39

Re: Objekt in einer DLL kapseln
 
Zitat:

Zitat von DelphiManiac
Was meinst du genau mit Automatisierungsobjekt??

Du erstellst für deine Klasse ein (COM-)Interface welches dann vom VB-Programmierer per Referenz in sein Projekt gezogen wird und verwendet werden kann. Beispiel liegen unter <Demos\ActiveX> bereit.

DelphiManiac 24. Apr 2007 13:24

Re: Objekt in einer DLL kapseln
 
@Bernhard Geyer:

Ich gucke mir das ActiceX Beispiel mal an. Danke


@alle:

In Delphi gibt es ja den Datentyp Single (einfache Genauigkeit) als 32 Bit Wert (mit Mantisse, Exponent...)

Ich nutzt den Datentyp und muss ihn als Rückgabetyp (bzw als Pointer) entgegen nehmen und dann den Wert
an die Adress schreibe, so wie ich das auch mit Integern mache, kein Problem,.

meine Frage ist nur, gibt es da Probleme mit VB?? eigentlich doch nicht, dort gibt es doch auch ein Fliesskommatyp
mit einfacher Genauigkeit, oder??

Gruß
und Dank

MStoll 24. Apr 2007 14:02

Re: Objekt in einer DLL kapseln
 
Ich habe so was ähnliches auch mal gemacht, allerdings etwas ausführlicher:

DLL:
Delphi-Quellcode:
var Objekte : array of TObject;

function CreateObject : integer; stdcall;
begin
     SetLength(Objekte, length(Objekte)+1);
     Objekte[high(Objekte)].create;
     result := high(Objekte);
end;

procedure MachWas(index : integer); stdcall;
begin
     Objekte[index].MachWas;
end;

procedure DestroyObject(index : integer); stdcall;
begin
     Objekte[index].Free;
end;

exports
    CreateObject,
    DestroyObject,
    MachWas;
Wenn du nun im Programm eine Klasse nach folgendem Muster erstellst:
Delphi-Quellcode:
type TMeineKlasse = class(TObject)
                    private
                       index : integer;
                    public
                       constructor Create;
                       destructor Destroy; override;
                       procedure MachWas;
                    end;

function CreateObject : integer; stdcall; external 'Beispiel.dll';
procedure DestroyObject(index : integer); stdcall; external 'Beispiel.dll';
procedure MachWas(index : integer); stdcall; external 'Beispiel.dll';

constructor TMeineKlasse.Create;
begin
     index := CreateObject;
end;

destructor TMeineKlasse.Destroy;
begin
     DestroyObject(index);
end;

procedure TMeineKlasse.MachWas;
begin
     MachWas(index);
end;
dann kannst du quasi Objekte "aus" der DLL benutzen. Es reicht dann völlig aus wenn du in der DLL für jede public-Methode sowie Konstruktor und die Free-Methode ne eigene Prozedur/Funktion mit dem Index als Parameter (außer beim Konstruktor) schreibst und diese exportierst. Find ich immer wieder praktisch, wenn man auch mal mehrere Instanzen eines Objektes aus einer DLL erzeugen und benutzen will.

Gruß
Michael


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:43 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz