Newsgroup: it.comp.lang.delphi
Titolo: [D5Ent] Interface + dll: Come utilizzare un oggetto dell'applicazione chiamante

Salve a tutti,
Ho un problema nell'utlilizzo di un oggetto creato in un eseguibile,
dall'interno di una dll che
possiede un puntatore all'interfaccia esportata dall'eseguibile. (mii
contorto :))
L'interfaccia esportata dall'applicazione principale è siffatta:
    IIntegratorNG_V1        = interface(IUnknown)
        ['{4085AA5D-9F5F-412B-B7A4-0B2C136AB7BB}']
        ...
        // Proprietà accessibili da INGServer
        function GetOperatorID:integer;
        property OperatorID:integer read GetOperatorID;
        function GetOperatorName:String;
        property OperatorName:string read GetOperatorName;
        function GetOperatorPassword:String;
        property OperatorPassword:string read GetOperatorPassword;
        function GetDataBase:TIBDatabase;
        property DataBase:TIBDatabase read GetDataBase;
        function GetSecurityService:TIBSecurityService;
        property SecurityService:TIBSecurityService read GetSecurityService;
    end;
All'interno della mia dll, ho una funzione di inizializzazione che
l'eseguibile principale richiama:
function InitModule(IServer:IIntegratorNG):IIntegratorModule; stdcall;
IServer è, ovviamente, l'interfaccia dell'eseguibile principale, il
risultato della funzione, invece,
è l'interfaccia esportata dalla dll.
Il corpo della funzione summenzionata è il seguente:
function InitModule(IServer:IIntegratorNG):IIntegratorModule;
begin
    Result:=Nil;
    if Assigned(FUserManager) then
    begin
        FUserManager.Interfaccia:=IServer;
        FUserManager.IBSecurityService:=IServer.SecurityService;
        Result:=FUserManager;
    end
    else
        raise INGException.Create('Istanza del form di UserManager
MANCANTE!');
end;
Da un'altra parte, utilizzo IBSecurityService per recuperare l'elenco degli
utenti sul server FireBird/Interbase 6.0.
Nel fare ciò, ottengo un'Exception relativa ad una violazione di accesso
dell'indirizzo "000000... Read of address
000000...".
Ma una dll, non condivide lo stesso spazio di indirizzi del processo
chiamante?
La febbre è più alta di quella misurata dal termometro?
Grazie per l'aiuto.
Saluti (me ne torno a letto, la stanza non smette di girare)

hai provato a sostituire la stdcall con SAFECALL?
Si, ho provato anche con safecall, ma il comportamento è lo stesso.
Allora, ho provato a semplificare il programma, realizzando una cosa simile:
    IIntegratorNG_V1        = interface(IUnknown)
        ['{4085AA5D-9F5F-412B-B7A4-0B2C136AB7BB}']
        function GetPannello:TPanel;
        property Pannello:TPanel read GetPannello;
    end;
    // Definizione dell'interfaccia dei Moduli per IntegratorNG
    TInitModuleProc = function(IServer:IIntegratorNG):IIntegratorModule;
safecall;
    TMostraGestioneUtenti = procedure; safecall;
    TApplicationInfo = procedure(Informazioni:TStringList); safecall;
    IIntegratorModule_V1    = interface(IUnknown)
        ['{E4D0F1EC-2FD1-4288-85FF-E556CC4596BF}']
        procedure AggiungiBottone; safecall;
    end;
L'eseguibile consta di un Form ed un pannello.
All'avvio, carica dinamicamente la dll ed effettua la chiamata a
"InitModule(InterfacciaApplicazione)".
Questa chiamata, inizializza il modulo e restituisce l'interfaccia dello
stesso.
Al pannello dell'eseguibile è legato un evento DblClick, al verificarsi di
tale evento,
viene richiamato il metodo del modulo "AggiungiBottone".
"AggiungiBottone", altro non fa che creare un componente TButton
e impostare come "Parent" il pannello ottenuto tramite la proprietà
"Pannello".
Questo risulta in :
- Access Violation in module Vcl50.bpl at ..... Read of address 000000..
- L'istruzione a "0x01cf383c" ha fatto riferimento alla memoria a
"0x022...". La memoria non poteva
essere "read".
Con botto finale e chiusura dell'applicazione.
Sto impazzendo, tutta la manualistica che trovo sulle interfacce è sempre,
rigorosamente, legata a COM/ActiveX.
Saluti
P.S.:
Ho provato a risponderti in email, mi ritorna errore (ormai è una sagra!)
dicendo
che l'account o non esiste o è disabilitato.

     TApplicationInfo = procedure(Informazioni:TStringList); safecall;
hai provato a mettere sharemem?
La butto li, visto che usi una tstringlist.
Anzi, se la stringlist non ha molti items potresti passare un pchar di 
una variabile alla quale assegni il text della tstringlist e fanc##o lo 
sharemem.
A

 sharemem.
In ogni caso, ho rimosso la funzione che prende la TStringList.
Allo stato attuale, l'applicazione giocattolo mette a disposizione (tramite
l'interfaccia)
la proprietà "Pannello". Essa, espone un oggetto TPanel (creato a design
time).
Dall'altra parte, la dll esporta un'interfaccia con un unico metodo
"AggiungiBottone" (senza parametri
nè valore di ritorno).
Nella risposta precedente, ci sono le dichiarazioni delle interface.
Provo a riformulare il problema:
E' possibile definire un'interfaccia che consenta di esportare un
"Componente Delphi"?
A me, per il momento, interessa che siano altre applicazioni Delphi ad
utilizzare
tale interfaccia.
Grazie per l'aiuto


Quando in DLL si usano dei componenti c'e' da tener conto del modo di
utilizzo dei packages.
Se sia nell'eseguibile che nella DLL usi i runtime packages allora stai a
posto, ma negli altri casi devi tener conto che avrai delle copie diverse di
Application e di tutte le altre variabili globali.
Utilizzando dalla DLL dei componenti creati nell'eseguibile rischi di
incasinare notevolmente le cose.
Personalmente ti consiglio, dato che hai "intrapreso" la via delle
interfacce, di costruirti delle interfacce per ogni cosa accessibile
nell'eseguibile. Se poi ti serve impostare qualche Parent in eventuali
componenti creati nella DLL, passa sempre degli HWindow ed utilizza il
costruttore della form CreateParented
Ciao,
Stefano

 tale interfaccia.
se fosse solo delphi, xche complicarsi la vita con i com?
Sembra che con .net zio billy voglia mandare i com in pensione....
A

 costruttore della form CreateParented
L'intenzione è quella di fornire un'interfaccia per ogni cosa utilizzabile
dai moduli dell'applicazione.
Il discorso inverso, invece, è più semplice. Infatti, per il momento, i
moduli presentano tutti un'interfaccia standard.
Adesso smanetto un pò con i bpl e poi aggiorno il thread :)
Grazie per l'aiuto.

 Sembra che con .net zio billy voglia mandare i com in pensione....
Sto spostando tutto in dei BPL ed il problema non si presenta!
Pare che gli oggetti scambiati da e per le dll non siano proprio
il massimo dell'affidabilità :)
Zio billy, sta cercando di mandare in pensione anche me con 'sto .Net.
Sto leggiucchiando qualcosina su C#, e mi sono tuffato in Python (sia
per integrarlo nei miei progetti, sia per avercelo come valida alternativa).
Non ho avuto modo, e tempo, per apprezzare le meraviglie del .Net
però questa migrazione mi infastidisce non poco. A te?