View Full Version : importazione classi da DLL
in un header ho dichiarato alcune classi astratte, contenenti solo metodi puri virtuali (virtual bla bla bla = 0); questo header l'ho incluso sia in un certo eseguibile, sia in una certa DLL; la DLL naturalmente avrà le sue classi derivate da quelle astratte contenute in questo header che forniranno le rispettive implementazioni, ed esporterà delle opportune funzioni che, chiamate dall'eseguibile, serviranno ad istanziare queste classi.
ora io mi chiedevo: è possibile fare in modo che di una certa classe una parte venga implementata dalla DLL e una parte dall'eseguibile? in pratica alcune funzioni di una certa classe non sono pure virtuali, ma sono normali funzioni (virtuali volendo, ma non è necessario e non credo nemmeno sia possibile nel mio caso) implementate dall'eseguibile; il codice di queste funzioni dunque nella DLL non appare, e questo già temo che sia un problema perché impedirebbe il linking, dico bene?
altrimenti pensavo di creare una classe derivata anche all'interno dell'eseguibile, in maniera tale da poter implementare alcune funzioni, solo che la rispettiva funzione esportata dalla DLL mi istanzierebbe la *sua* classe derivata, non la mia... :\
come posso risolvere? è possibile quello che chiedo? o andrebbe fatto necessariamente in maniera "manuale", cioè lavorando di puntatori a funzioni in runtime?
thx. :)
in un header ho dichiarato alcune classi astratte, contenenti solo metodi puri virtuali (virtual bla bla bla = 0); questo header l'ho incluso sia in un certo eseguibile, sia in una certa DLL; la DLL naturalmente avrà le sue classi derivate da quelle astratte contenute in questo header che forniranno le rispettive implementazioni, ed esporterà delle opportune funzioni che, chiamate dall'eseguibile, serviranno ad istanziare queste classi.
ora io mi chiedevo: è possibile fare in modo che di una certa classe una parte venga implementata dalla DLL e una parte dall'eseguibile? in pratica alcune funzioni di una certa classe non sono pure virtuali, ma sono normali funzioni (virtuali volendo, ma non è necessario e non credo nemmeno sia possibile nel mio caso) implementate dall'eseguibile; il codice di queste funzioni dunque nella DLL non appare, e questo già temo che sia un problema perché impedirebbe il linking, dico bene?
altrimenti pensavo di creare una classe derivata anche all'interno dell'eseguibile, in maniera tale da poter implementare alcune funzioni, solo che la rispettiva funzione esportata dalla DLL mi istanzierebbe la *sua* classe derivata, non la mia... :\
come posso risolvere? è possibile quello che chiedo? o andrebbe fatto necessariamente in maniera "manuale", cioè lavorando di puntatori a funzioni in runtime?
thx. :)
qualsiasi dll è un'eseguibile a parte ed è estraneo all'exe principale nei metodi e classi.
La dll può essere chiamata dall'exe dalle funzioni che vengono esportate.
Per esempio se crei un oggetto nel progetto che richiama la dll per far vedere l'oggetto alla dll devi passare il puntatore dell'oggetto tramite funzione alla dll e magari renderlo globale nella dll. Se per esempio nei calcoli della dll l'oggetto perde il focus (lost device per esempio) dal progetto chiamante bisogna fare in modo di ripassare il puntatore dell'oggetto alla dll.
Un'altro esempio è un oggetto creato invece dalla dll esso non è visto dal progetto chiamate se non con un ritorno del suo indirizzo e opportunamente inizializzato cioè non a NULL per le operazioni da fare intendo.
L'exe principale (chiamante) ha un suo ciclo di vita mentre la dll ne ha un'altro.
La dll (se viene passato l'oggetto da progetto principale e il suo indirizzo) la dll può accederci.
Le classi non possono essere viste dalla dll e le classi della dll non hanno influenza sull'exe chiamante
The3DProgrammer
27-07-2005, 11:05
uhm
secondo me, se la DLL usa le funzioni nn definite nella sua dichiarazione di classe, ovviamente ci sono problemi di link (correggo, + che di link di undeclared identifier, in quanto la funzione proprio nn esiste) come hai detto tu. Se invece nn usa queste funzioni e viene implementata una funzione che ritorna un puntatore ad un'istanza di quella classe, potrebbero cmq esserci problemi di type conversion, questo xkè anke se hanno lo stesso nome, alla fine sono due classi diverse. Anche se il compilatore nn si accorgerebbe del problema in quanto il linking con la DLL è dinamico ( e il puntatore che avrai definito alla funzione nella DLL avrà come tipo di ritorno un puntatore alla classe presente nell'eseguibile, il che è perfettamente lecito) nn so cosa potrebbe succedere a runtime (potresti fare una bella prova usando dynamic_cast).
ciauz
The3DProgrammer
27-07-2005, 11:08
tra l'altro, ma xkè vuoi rovinarti la vita facendoti ste domande? :D 
skerzo ciauz :ciapet:
The3DProgrammer
27-07-2005, 11:15
cancella i primi 2 post:D
nn avevo capito bene la domanda :muro: 
quindi tu dici che la dichiarazione della classe è identica per eseguibile e DLL (quindi le funzioni dichiarate ci sono tutte) ma mancano alcune definizioni di funzioni, che viceversa sono presenti nell'eseguibile? Se si, allora secondo me potrebbe anke funzionare, a patto ke la DLL nn usi le funzioni non definite (cosa ke porterebbe a problemi di linkage). Il tutto, sempre col beneficio del dubbio
scusa, ma mi sono appena alzato e ho avuto una brutta notizia ( ho preseo un brutto voto a basi di dati  :doh: )
ciauz
The3DProgrammer
27-07-2005, 11:40
mi ha pigliato sta cosa:D
appena provato, e funziona perfettamente ;)
ora metto il codice del progetto
The3DProgrammer
27-07-2005, 11:51
ecco il progetto, scritto in 5 minuti quindi potrei aver fatto qualke baggianata
cmq, secondo me funziona xkè come saprai, le funzioni di una classe, una volta compilate, sono funzioni standard con calling convention __thiscall (quindi con push di this in cima allo stack prima della chiamata). Di conseguenza, alla chiamata del metodo, viene chiamata la funzione presente nell'eseguibile, passando come this l'oggetto creato dalla DLL. Spero di aver kapito quello ke intendevi e di nn aver detto un mare di baggianate:D
ciauz
dunque, si, funziona, però la DLL non implementa nulla della classe A; era proprio questo il mio problema: l'eseguibile deve implementare alcune funzioni, la DLL ne deve implementare altre; ora faccio delle prove sul tuo progetto (cmq grazie per l'aiuto, sei stato molto gentile :)).
PS, x okay: ma che hai detto?!? :mbe: :mbe:
hai scritto cose per metà non inerenti e per l'altra metà apparentemente errate...
nah, non ci riesco, non linka, come supponevo; e se lavoro con le funzioni pure virtuali poi non posso manco istanziare la classe derivata perché la DLL non implementa alcune delle funzioni pure virtuali (appunto).
non c'è un modo di risolvere questo problema? o devo necessariamente applicare un altro design?
un altro design che mi viene in mente è il seguente: eliminare dalla classe originale (chiamiamola A) le funzioni che devono essere implementate nell'eseguibile, e metterle in un altra classe (facciamo B) la quale ha anche come variabile membro un puntatore a un'istanza di A ottenuta dalla DLL.
unico contro: la DLL non può chiamare le funzioni implementate dall'exe; non che mi serva a dir la verità, però insomma, potrebbe sempre rivelarsi una limitazione... non esistono design migliori?
thx :)
si rileggendo il mio post noto che è scritto alla buona, comunque intendevo come uso io dll e lib e cioè funzioni esterne chiamate e gestite da altri exe o progetti senza riscrivere lo stesso codice è per questo che sono nati tali moduli. Oppure celare funzioni e quindi algoritmi da non far vedere a chi usa tale dll e lib nei propri progetti ecc. ecc.
Ho capito che vuoi leggere le classi e i metodi dell'exe dalla dll e/o viceversa.
1. per fare questo non servono moduli esterni dll o lib in quanto implementi tutto sul progetto principale.
2. Il programma chiamante non può accedere alla dll o lib nelle sue classi e o metodi e viceversa in quanto sono 2 circuiti chiusi, di comunicazione  il chiamante non ha l'entry point della dll o lib che è un'altro programma appartenente solo a se stesso la dll o lib ha il suo entry point e le varie tabelle delle funzioni esportate a cui può accedere il chiamante solo per passare argomenti o variabili che nella funzione verranno elaborate.
3. Io pure per un pò ci persi tempo ma non è possibile non ci sono riuscito (certo che se ci riesci fammelo sapere)
Per questo motivo tratto dll e lib per il lavoro a cui sono dedicate e cioè chiamo le funzioni della dll e lib e ritorno al chiamante.
ciao
ehm... ti capisco sempre meno...
si rileggendo il mio post noto che è scritto alla buona, comunque intendevo come uso io dll e lib e cioè funzioni esterne chiamate e gestite da altri exe o progetti senza riscrivere lo stesso codice è per questo che sono nati tali moduli. ma che c'entra... -.-'
i file che condivido tra il progetto della DLL e quello dell'eseguibile sono solo headers, mica sorgenti...
1. per fare questo non servono moduli esterni dll o lib in quanto implementi tutto sul progetto principale. scusa tu che ne sai del mio progetto... a me serve che quelle classi siano implementate in librerie esterne perché non devo essere io ad implementarle; o meglio, io ne implemento una versione, ma devo prevedere la futura possibilità che altre persone (o anche io stesso) possano implementarne altre e aggiornare il programma senza riavviarlo (te la faccio breve: si tratta di un server con dei plugins che potranno essere installati e rimossi dinamicamente).
quindi il fatto che quelle classi stiano in librerie a parte a me serve eccome...
2. Il programma chiamante non può accedere alla dll o lib nelle sue classi e o metodi e viceversa in quanto sono 2 circuiti chiusi di comunicazione, questo discorso non ha senso...
a parte il fatto che una volta caricato il modulo nel mio processo nessuno mi impedisce di andare a smanazzare nella sua sezione di dati, pur non conoscendone il suo layout e il significato di ogni singolo byte (infatti i dangling pointers "intra-process" a volte sono pericolosi anche in modalità protetta, non c'è niente da fare...); ma a parte questo non vedo perché una DLL non possa esportare una classe... i moduli possono esportare i simboli che vogliono.
il chiamante non ha l'entry point della dll o lib leggiti le specifiche del formato PE: l'offset dell'entry point sta scritto nell'Optional Header (opzionale dei file obj ma richiesto in qualsiasi immagine) e lo puoi leggere direttamente dalla RAM quando ti pare; sommandolo all'HMODULE del modulo hai l'indirizzo paro paro.
che è un'altro programma appartenente solo a se stesso delirio... :confused:
deja vu: una frase del genere l'ho scritta una volta anche a un'altra persona, ma giuro che questo adesso è molto peggio... :confused:
la dll o lib ha il suo entry point e le varie tabelle delle funzioni esportate dico, vabbè che in teoria in un file PE possono esserci fino a 96 sezioni, ma ora non montiamoci la testa... :asd: qualsiasi linker mi genera una sola sezione .edata... :asd:
a cui può accedere il chiamante solo per passare argomenti o variabili che nella funzione verranno elaborate. e se a quella mente bacata di chiamante venisse tante volte in mente di cancellare queste 700000 tabelle chi gli impedirebbe di farlo? :rolleyes:
e se volesse riscriverle a suo piacimento in maniera tale da dirottare le chiamate di funzioni (tecnica peraltro molto usata da alcuni tipi di virus)? :rolleyes:
3. Io pure per un pò ci persi tempo ma non è possibile non ci sono riuscito (certo che se ci riesci fammelo sapere) se ti riferisci all'esportare classi ci sono riuscito 1000 volte; se ti riferisci all'esportare classi implementate solo parzialmente non ci riesco manco io (bisogna necessariamente lavorare di puntatori a funzioni in runtime).
Per questo motivo tratto dll e lib per il lavoro a cui sono dedicate e cioè chiamo le funzioni della dll e lib e ritorno al chiamante. scusa, ma a parte tutto, tu sai cos'è un lib?
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.