AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

DLL Parser Plugins

Ein Thema von Alaitoc · begonnen am 15. Dez 2009 · letzter Beitrag vom 29. Dez 2009
 
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#10

Re: DLL Parser Plugins

  Alt 15. Dez 2009, 18:14
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
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
 

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:27 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