Newsgroup: it.comp.lang.delphi
Titolo: Info sui package

Ciao a tutti.
dunque il problema è questo:
ho un applicativo che utilizza una serie di package caricati a run time 
con LoadPackage. I package esportano, oltre ad oggetti, anche una serie 
di funzioni e procedure.
Ora, se nelle opzioni di progetto abilito la compilazione con i package 
a run time e, nella lista dei package do un nome di un package qualsiasi 
(anche che non viene utilizzato) tutto funziona correttamente ovvero gli 
oggetti vengono allocati correttamente e le funzioni si richiamano. Se 
pero' disabilito questa opzione oppure non scrivo nulla nella lista dei 
package gli oggetti non vengono allocati (non vengono registrate le 
classi) ma le funzioni vengono richiamate correttamente.
Qualcuno puo' dirmi cosa succede? E' normale che in un package qualcosa 
funzioni bene ed un'altra cosa no?
Nota: utilizzo Delphi 5 Professional
Grazie a chiunque possa rispondermi,
David

 funzioni bene ed un'altra cosa no?
Non saprei dirtelo con precisione, anche perchè non sono certo di aver 
capito bene la parte precedente del tuo messaggio, ma il funzionamento 
che dovresti ottenere è il seguente:
1)
compilazione SENZA runtime package:
il codice delle unit che contengono le tue classi, ivi comprese 
procedure e funzioni, vengono incorporate nel tuo eseguibile finale, 
selezionate in base all'effettivo utilizzo che ne fai;
2)
compilazione CON runtime package:
l'applicazione si collega dinamicamente ai package (specificati nelle 
opzioni) e ai package da cui questi dipendono.
Se inserisci nomi di package runtime che non corrispondono a quelli 
effettivamente utilizzati, non so quali effetti collaterali tu possa 
ottenere, ma forse ho compreso male io la situazione.
Ciao,
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)

Forse dico una cavolata ma volevo utilizzare i package un po' come si 
utilizzano le dll, ovvero utilizzarli all'interno di un applicativo 
senza la necessità di dichiarare a monte il/i package utilizzati.
Mi spiego:
Il programma principale legge da un file di testo una serie di package 
istallati e abilita le funzioni corrispondenti. Nello specifico ogni 
package contiene una funzione che ritorna un nome da inserire nei menù 
ed il nome della finestra più un'oggetto di tipo TForm che gestisce la 
funzione stessa.
Quindi non posso dire a priori quali package andro' ad utilizzare in 
quanto non lo so a design time.
Quello che mi lascia perplesso è che la funzione contenuta all'interno 
del package funziona regolarmente sia che eseguo una compilazione con 
runtime package che non; ma la RegisterClass contenuta all'interno del 
package nella sezione initialization fallisce se ho dichiarato "compila 
senza i runtime package" con la conseguenza che la form non verrà 
visualizzata in quanto la funzione GetClass (o FindClass che sia) 
fallisce. Ho provato anche ad esportare una funzione che forza la 
chiamata alla RegisterClass ma l'esito è lo stesso.
Idee?
Grazie,
David

 [...]
Forse ho capito: si tratterebbe di usare i package come una sorta di plugin?
In tal caso, devi ovviamente attivare la compilazione con i runtime 
package includendo nell'elenco gli stessi identici package da cui 
dipendono i package aggiuntivi che hai creato.
Tuttavia, ciò che intendi realizzare, se questa volta sono riuscito a 
comprendere bene la problematica, si ottiene caricando i package BPL a 
runtime usando le funzioni di supporto /LoadPackage/ e /UnloadPackage/.
Al momento, non ho molto tempo per dilungarmi. :-/
Ne ho (forse) la possibilità durante questo weekend (ADSL casalinga 
permettendo, uffa).
Per ora, confermami se il caso a cui si riferiscono le mie 
considerazioni è quello che ho descritto. :-)
E' probabile poi che altri intervengano a darti una mano. ;-)


 E' probabile poi che altri intervengano a darti una mano. ;-)
Speriamo ma fino ad ora nisba.
Ciao e grazie,
David

 Non ti preoccupare. Il problema è che cercando in giro non si trova nulla.
Ti arrendi troppo presto. ;-)
Prova qui:
http://delphi.about.com/od/objectpascalide/l/aa010901a.htm


 
http://delphi.about.com/od/objectpascalide/l/aa010901a.htm
Magari. L'avevo già letto ed ho eseguito le istruzioni alla lettera 
(anche tramite esempi presi dalla borland). Ma il problema persiste.
Ps. Ti posto un po' di codice.
Questo è il codice per il caricamento ed l'esecuzione di una form 
contenuta in un package (il punto dolente è sulla funzione GetClass)
Procedure TFormMain.Lancia_Package_Form(Const PackageName, FormName : 
String);
Var
   Package : HModule;
   Classe  : TPersistentClass;
   Form    : TForm;
begin
   // ----------------------
   // Caricamento Package
   // ----------------------
   Try
     Package := LoadPackage(PackageName);
   Except
     Package := 0;
   End;
   // ----------------------
   // Package valido ?
   // ----------------------
   If Package <> 0 Then
      Begin
        // ----------------------
        // Caricamento classe
        // ----------------------
        Try
          Classe := GetClass(FormName);
        Except
          Classe := Nil;
        End;
        // ----------------------
        // Classe valida ?
        // ----------------------
        If Classe <> Nil Then
           Begin
             // ---------------------------
             // Creazione form ed utilizzo
             // ---------------------------
             Form         := 
(TComponentClass(Classe).Create(Application) As TForm);
             Form.Caption := 'Questa è la form '+FormName+' del package 
'+PackageName;
             Form.ShowModal;
             Form.Free;
           End;
        // ----------------------
        // Distruzione package
        // ----------------------
        ScaricaPackageSicuro(Package);
      End;
End;
Questo è il codice per l'esecuzione di una funzione nel package (che 
funziona sempre):
Procedure TFormMain.Lancia_Package_Funzione(Const PackageName, FunName : 
String; Var FormName : String);
Type
   MyFunc = Procedure(Sender : TComponent; Var NomeForm : String);
Var
   Package : HModule;
   Func    : MyFunc;
begin
   FormName := '';
   // ----------------------
   // Caricamento Package
   // ----------------------
   Try
     Package := LoadPackage(PackageName);
   Except
     Package := 0;
   End;
   // ----------------------
   // Package Valido ?
   // ----------------------
   If Package <> 0 Then
      Begin
        // ----------------------
        // Puntatore Funzione
        // ----------------------
        @Func := GetProcAddress(Package, PChar(FunName));
        // ----------------------
        // Puntatore Valido ?
        // ----------------------
        If Assigned(Func) Then Func(Self, FormName);
        // ----------------------
        // Distruzione package
        // ----------------------
        ScaricaPackageSicuro(Package);
      End;
End;
E, dulcis in fundo, questo è il codice per l'unload di un package in 
maniera sicura:
Procedure TFormMain.ScaricaPackageSicuro(Module: HModule);
Var
   I : Integer;
   M : TMemoryBasicInformation;
Begin
   // ---------------------------------------------------
   // Ricerca tutti i componenti istanziati dal package
   // ---------------------------------------------------
   For I := Application.ComponentCount - 1 Downto 0 Do
       Begin
         VirtualQuery(GetClass(Application.Components[I].ClassName), M, 
SizeOf(M));
         If (Module = 0) Or (HMODULE(M.AllocationBase) = Module)
         Then
           Application.Components[I].Free;
       End;
   // ---------------------------------------------------
   // Deregistra tutte le classi registrate dal package
   // ---------------------------------------------------
   UnRegisterModuleClasses(Module);
   // ---------------------------------------------------
   // Scarica il package
   // ---------------------------------------------------
   UnLoadPackage(Module);
End;

 funzioni bene ed un'altra cosa no?
Il problema dei package è che richiedono altri package per funzionare.
Ergo, se vuoi visualizzare una form in un package da usare come plug-in,
allora devi avere i package base di delphi(per intenderci, quelli dove
sono definiti i controlli base tipo la form), altrimenti non
funzioneranno.
Diverso è il discorso per le classi tue che derivano da TPersistent,
quelle dovrebbero funzionare a prescindere con LoadPackage, purché
ovviamente tu non usi classi che sono incluse in altri package.
Ultima cosa: come regola generale usare i package plug-in solo
abilitando la compilazione con i run-time packages.
Ciao,
Andrea