Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi DLL Parser Plugins (https://www.delphipraxis.net/144737-dll-parser-plugins.html)

Alaitoc 15. Dez 2009 13:49


DLL Parser Plugins
 
Hallo zusammen,

ich habe mehrere Parser, die ich mir je nach Datei über eine Factory erstelle und wo ich dann
ein Interface mit einem Execute()-Befehl zurückgebe.

Ich würde mir nun wünschen, dass ich diese Struktur in Plugins auslagere. Also das für jeden Dateityp ein Plugin vorhanden ist.
Über die Suche habe ich zwar das Tutorial von Sakura gefunden, jedoch braucht man dafür ShareMem.
Was gibt es für Möglichkeiten bzw gibt es Möglichkeiten ohne ShareMem?

MfG Alaitoc

himitsu 15. Dez 2009 14:00

Re: DLL Parser Plugins
 
Zitat:

Möglichkeiten ohne ShareMem?
Indem man alles NICHT verwendet, welches auf den Delphi-Speichermanager setzt.

keine dynamischen Arrays, keine String, AnsiString, UnicodeString und ähnliches

(WideString läuft über den Speichermanager der OleAuth.dll)

Mithrandir 15. Dez 2009 14:13

Re: DLL Parser Plugins
 
Wenn man ein wenig Vorbildung in ANSI-C hat, ist es gar nicht soooo schwer, ohne Strings und Co. zurecht zu kommen. Man muss nur dran denken, selbst genug Speicher anzufordern, und ihn auch wieder freizugeben (bevor man den Zeiger darauf vernichtet hat. :mrgreen: ).

Und denk dir bloß eine Dateiendung aus. "dll" treibt einigen Zeitgenossen die Schweißperlen auf die Stirn... :tongue:

Alaitoc 15. Dez 2009 14:22

Re: DLL Parser Plugins
 
Da ich den Begriff ShareMem noch nie gehört hatte und da es extra erwähnt wurde...dachte ich
das es eine externe Unit ist... :wall: :wall: :wall:

Ich schau mir mal das Tutorial von Sakura nochmal genauer an ^_°

MfG Alaitoc

Mithrandir 15. Dez 2009 14:36

Re: DLL Parser Plugins
 
Dir muss aber klar sein, dass du nicht nur die Unit einbinden musst, sondern auch die entsprechende dll (Name vergessen) mitliefern musst.

Außerdem schließt du so auch andere Sprachen, primär C/C++ aus, was ja gerade der Vorteil an dlls sein soll. ;)

Alaitoc 15. Dez 2009 14:43

Re: DLL Parser Plugins
 
Naja zuerst hatte ich es mit DLL+ versucht, jedoch
gab es da irgendein Problem. Ich glaube weil ich bisher noch Objekte als Übergabeparameter ( zur Ausgabe ) habe, das
dürfte so nicht klappen... :gruebel:

Wahrscheinlich muss ich mir da auch noch Gedanken zur Struktur machen und die dementsprechend überarbeiten... :|

Mithrandir 15. Dez 2009 14:46

Re: DLL Parser Plugins
 
Was C und Delphi gemeinsam haben, sind Records (in C heißen die halt structs). Zeiger darauf kann man problemlos zwischen DLLs austauschen. So realisiere ich gerade eine generische Pluginsschnittstelle für meinen kleinen Audioplayer...

Alaitoc 15. Dez 2009 14:53

Re: DLL Parser Plugins
 
Ah Danke, werde mal schauen ob ich meins so umstrukturieren kann( Ich hoffe ^^ )
und ob der Aufwand nicht allzu groß ist.

MfG Alaitoc

MarioM. 15. Dez 2009 15:21

Re: DLL Parser Plugins
 
Zitat:

Zitat von Daniel G
Und denk dir bloß eine Dateiendung aus. "dll" treibt einigen Zeitgenossen die Schweißperlen auf die Stirn... :tongue:

Sei vorsichtig; wenn R0815 das liest, bezichtigt er Dich gleich als beleidigend und jagt Dir den Cheffe auf den Hals. Da bist Du Deinen Mod-Status schneller los, als Dir recht ist :zwinker:

Zum Thema:
Super danke; ich stehe gerade vor einem ähnlichen Problem und kann mit der Hilfestellung gut was anfangen :)

Elvis 15. Dez 2009 18:14

Re: DLL Parser Plugins
 
Hehe, plugins + Interfaces sind so eine Pet-Disciplin von mir... ;-)

Generell ist es bei sowas immer gut, sich auf das u beschränken, was auch über COM funktioniert.
Also...
  • Keine Delphi-Stirng, dafür gehen WideStrings.
  • Keine Klassen, dfür gehen Interfaces.
  • Keine dynamischen Arrays, du kannst hierfür Listenklassen nehmen, die ein Interface implementieren.

Wenn du Interfaces nutzt[1], dann denke daran, dasss sie sich wenigstens ein bissel wie COM-Objekte benehmen sollten.
Das heißt alle Methoden sollte als Calling convention "safecall" nehmen, und alle sollten eine eindeutige GUID haben.


Hier mal ein Bleistift:
Solche eine DLL in Delphi, wäre so interoperabel, dass man sie sogar in C# nutzen könnte.

Delphi-Quellcode:
library SampleInterfaceDLL;

uses
  Dialogs;

type
  ISample = interface(IUnknown)
  ['{C9B334E4-BDAE-419E-9305-143B2C454CEA}']
    function Get_Value : WideString; safecall;
    procedure Set_Value(const value : WideString); safecall;

    procedure ShowValue; safecall;
    property Value : WideString
      read Get_Value
      write Set_Value;
  end;

  TSample = class(TInterfacedObject, ISample)
  private
    fValue : WideString;
    function Get_Value: WideString; safecall;
    procedure Set_Value(const aValue: WideString); safecall;
  public
    procedure ShowValue; safecall;
    property Value : WideString
      read Get_Value
      write Set_Value;
  end;

procedure CreateSample(out instance : ISample); stdcall;
begin
  instance := TSample.Create();
end;

function GetValueLength(const instance : ISample) : Integer; stdcall;
begin
  result := Length(instance.Value);
end;

exports
  GetValueLength,
  CreateSample;

{ TSample }

function TSample.Get_Value: WideString;
begin
  result := fValue;
end;

procedure TSample.Set_Value(const aValue: WideString);
begin
  fValue := aValue;
end;

procedure TSample.ShowValue;
begin
  ShowMessage('From Delphi: ' + Value);
end;

end.
Code:
[ComVisible(true)]
[Guid("C9B334E4-BDAE-419E-9305-143B2C454CEA")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ISample
{
   String Value
   {
      [return: MarshalAs(UnmanagedType.BStr)]
      get;
      [param: In, MarshalAs(UnmanagedType.BStr)]
      set;
   }

   void ShowValue();
}

class ManagedSample : ISample
{
   public String Value { get; set; }

   public int GetLength()
   {
      // Delphi wird mit hier mit "this" klarkommen, da es als ISample genutzt werden kann
      return DelphiImports.GetValueLength(this);
   }

   public void ShowValue()
   {
      Console.WriteLine("From .Net {0}", Value);
   }
}

static class DelphiImports
{
   [DllImport("SampleInterfaceDLL")]
   static extern void CreateSample([MarshalAs(UnmanagedType.Interface)]out ISample instance);

   public static ISample CreateSample()
   {
      ISample instance;
      CreateSample(out instance);
      return instance;
   }

   [DllImport("SampleInterfaceDLL")]
   public static extern int GetValueLength([MarshalAs(UnmanagedType.Interface)]ISample instance);
}

class Program
{
   static void Main(string[] args)
   {
      var delphiInstance = DelphiImports.CreateSample();

      delphiInstance.Value = "Test";
      var l1 = DelphiImports.GetValueLength(delphiInstance);

      var managedInstance = new ManagedSample { Value = "Def" };
      var l2 = managedInstance.GetLength();

      Array.ForEach(new[] { delphiInstance, managedInstance },
                    i => i.ShowValue());
   }
}
Hiermit könntest du sogar einen Parser in C# schreiben:
Code:
[ComVisible(true)]
[Guid("C9B334E4-BDAE-419E-9305-143B2C454CEA")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ISample
{
   String Value
   {
      [return: MarshalAs(UnmanagedType.BStr)]
      get;
      [param: In, MarshalAs(UnmanagedType.BStr)]
      set;
   }

   void ShowValue();
}

class ManagedPlugin : ISample
{
   public String Value { get; set; }

   public void ShowValue()
   {
      Console.WriteLine("From .Net {0}", Value);
   }
}

static class Exports
{
   [DllExport]
   static void CreateSample([MarshalAs(UnmanagedType.Interface)]out ISample instance)
   {
      instance = new ManagedPlugin { Value = "Managed Plugin!" };
   }

   [DllExport]
   public static int GetValueLength([MarshalAs(UnmanagedType.Interface)]ISample instance)
   {
      return (instance.Value ?? "").Length;
   }
}
[1]und das willst du weil platte C-kompatible DLLs bestenfalls als menschenverachtende Folter in Den Haag verhandelt werden sollten


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:05 Uhr.
Seite 1 von 3  1 23      

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