Gå til innhold

Dynamiske pakker i Delphi, HJELP! (her også =P)


Anbefalte innlegg

Jeg har visst enda fler spørsmål jeg, og jeg syntes ikke dette passet inn under den gamle tråden min. Men jeg lurer på hvordan man skal bruke dynamiske pakker i Delphi. Altså jeg har et program, og vil at det skal kunne laste inn noe som plugins (som jeg har laget selv, selvfølgelig i Delphi).

Har prøvd tutorials på delphi.about.com uten særlig hell, så jeg lurte på om noen her kunne gi meg en metode å laste sånne pakker inn i programmet uten for mye stress. Vil ha det inn i en funksjon som retunerer True hvis pakken finnes, og False hvis den ikke finnes.

 

Takker på forhånd.

 

EDIT: Vil ha innspill på hvordan man kan lage egne plugins til programmer man har lagd, disse plugin-ene skal lastes når man trenger de. Noen som har forslag?

Endret av hjahre
Lenke til kommentar
Videoannonse
Annonse

Jeg ser to muligheter her.

 

1. Lage funksjonalitet i DLL, som funksjoner som publiseres via "export;". Du laster inn denne DLLen via LoadLibrary. Denne metoden er litt ekkel, synes jeg, fordi du må definere funksjonene, som DLLen kommer til å implementere, på forhånd, men så er det ingenting som tvinger deg til å skrive dem som du har definert. Og så må du selv manipulere pointere til prosedyrer o.l. for å få tak i dem (tror jeg). Men denne er kanskje raskest å lage.

 

2. Metoden jeg liker best (fordi den er ryddig) er COM / ActiveX / OLE Automation (Microsoft har brukt forskjellige navn over tid, så jeg er ikke sikker på hva som er riktig). Du definerer en Interface eller flere i en TypeLibrary (og lagrer denne i en separat TLB fil, som registreres via Borlands TRegSvr.exe), og så implementerer du den definerte funksjonaliteten i hver plugin DLL. Den DDLen blir da ActiveX server (eller COM server, whatever). Når du lager en ny plugin DLL, lager du den som New / ActiveX library. Denne skal da inneholde en eller flere klasser som implementerer de Interfacene du har definert. Når du trykker på New / Automation object, får du opp type library editor. I rooten av type library må du sette opp at den "Uses" TLB filen du nettopp har definert og registrert, mens i CoClass definisjonen setter du opp at den "Implements" den Interface du ønsker og skriver funksjonalitet inn i placeholdere for prosedyrer som du får automatisk. I hovedapplikasjonen bruker du Interface definisjon fra samme TLB. Du må informere hovedapplikasjonen om hvor automation server(e) befinner seg - altså, "ServerDLLNavn.KlassNavn" for å kunne starte de. Og selvfølgelig må du registrere hver plugin-dll via regsvr32 (MS registreringsverktøy, ligger under Windows) eller via installasjonsprogrammet ditt.

 

Uff, det ble litt langt, men nå har jeg i hvert fall forklart både deg og meg hvordan man kan sette opp en fleksibel plugin-arkitektur. Dette minner veldig om det jeg har sett hos FinalBuilder (jeg har skrevet ca. 10 CustomActions for den), så du kan si at jeg stjal noen ideer fra dem. Men så har jeg ikke sett kildekoden til applikasjonen, så jeg har gjettet litt også. FinalBuilder og dokumentasjon til den kan lastes ned gratis, du betaler hvis du bruker den for mer enn 30 dager (noe vi gjør).

Lenke til kommentar

Er ikke helt sikker på hvilken metode jeg skal bruke, for jeg skal lage en mediespiller, og jeg vil at dette programmet skal laste inn den nødvendige pluginen (egentlig en ActiveX kontroller) for filtypen som skal spilles av. Programmet mitt skal takle QuickTime, RealMedia og WindowsMedia. Altså når man skal spille av f.eks. en wmp-fil så laster programmet automatisk inn pluginen for avspilling, forutsatt at brukeren har valgt å installere pluginen og har installert riktig kodek (installasjonsprogammet sjekker hvilke som er kodeker som er lagt inn og installerer plugins deretter, eller ber brukeren installere de nødvendige kodekene for å få full funksjonalitet ut av programmet).

 

Skal jeg gå for metode 2, eller er det noen andre metoder som funker? Jeg kan selvfølgelig prøve å få programmet til å laste inn nødvendige activex komponenter i runtime, altså "lage" de sjøl når programmet kjører. Men har en følelse av at det kan bli litt vanskelig.

Fler innspill? trenger virkelig å ha den funksjonaliteten i programmet mitt...

Lenke til kommentar
  • 1 måned senere...

For å ta et godt eksempel på en eksisterende mediaspiller med plug-in arkitektur så har vi Winamp. Winamp bruker ikke ActiveX i sin plug-in arkitektur men regulære funksjoner. Alle input plug-ins (plug-ins som dekoder lyddata) eksporterer en funksjon som heter winampGetInModule2. Når Winamp starter opp så laster den inn alle DLL filer i plugins mappa som matcher in_*.dll. Den kaller så winampGetInModule2 funksjonen i hver DLL for å bygge opp en liste over input plug-ins og hvilke filtyper de støtter. winampGetInModule2 funksjonen returnerer en pointer til en datastruktur (struct i C++, record i Delphi) som videre inneholder pointers til flere funksjoner og data om input plugin.

 

Windows Media Player benytter seg av DirectShow arkitekturen til Microsoft som er ActiveX basert. Alle filtre (som plugins her kalles) er registrert i registeret med hver sin CLSID (GUID for klasser). Det finne et bestemt interface for filtre.

 

Jeg forstår ikke hvorfor du ikke rett og slett benytter deg av DirectShow (eller enda bedre DirectMedia Objects) i ditt program. Ta en titt på DirectX SDK fra Microsoft. Det finnes også en haug med eksempler der ute.

Lenke til kommentar
  • 1 måned senere...

Ett spørsmål jeg håper noen av dere der ute kan svare på. Jeg skal lage et program med plugin-funksjonalitet. Har fått til det meste, men når det kommer til funksjoner og prosedyrer i pluginen så blir alt helt feil, har sett på noen eksempler på dette (f.eks. på denne siden; http://www.mdata.gr/MDataNews/DeveloperTip...micpackages.htm) men får det ikke til. Skal prøve på det de gjør i eksempel 1 der. Jeg har lagd en applikasjon med 2 former, sånn som det står, jeg har lagt den ene formen inn i en pakke og linka den til applikasjonen. Jeg har også laget en pakke for pluginen, alt går greit, inntil jeg skal kalle opp prosedyren min.

 

Form 1;

uses 
 unit2

procedure TForm1.button1click(sender: tobject);
begin
vis(edit1.text);
end;

 

Form 2;

ype
 TForm2 = class(TForm)
 private
   { Private declarations }
 public
   { Public declarations }
   procedure vis(s: string); virtual;
 end;

//var
//  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.vis(s: string);
begin
end;

end.

 

Form3 pluginen

uses
  ... unit2;

type
 TForm3 = class[(TForm2)
 private
   { Private declarations }
 public
   { Public declarations }
   procedure vis(s: string); override;
 end;

var
 Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.vis(s: string);
begin
ShowMessage(s);
end;

procedure TForm3.create(sender: tobject);
begin
inherited;
end;

initialization
 RegisterClass( TForm3 );
finalization
 UnRegisterClass( TForm3 );

end.

 

Og når jeg i form1 har kalt prosedyren vis, og skal kompilere det, så står det: "Undeclared identifier: 'vis'" jeg aner ikke hvorfor, noen som kan hjelpe meg?

 

TAkker på forhånd ;)

 

EDIT:

fikk det til :w00t: :!: :D måtte bare ha dette som kode

if pakke <> 0 then
try
 Vindu := FindClass('Tform3');
except
 vindu := nil;
end;

vinducom := TComponentClass(Vindu).Create(Application);

with vinducom as TForm2 do
vis(Edit1.text);

 

Vinducom er en global variabel

Endret av hjahre
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...