2009-11-17 3 views
5

Dopo il this question, ho bisogno di sapere quali principi devono essere seguiti per rendere l'incapsulamento di una classe in una DLL compatibile con un'altra versione di Delphi. Ho creato una classe utilizzando la funzione generics in RAD2010 e ho creato una DLL che ha una funzione che restituisce un'istanza di essa. Quando ho provato a utilizzare la dll utilizzando BDS2006 o Delphi 6, la DLL non ha funzionato come previsto. Ma se uso RAD2010 su un altro computer, non ci sono problemi. È causato dall'utilizzo della funzione non disponibile nella precedente versione di Delphi (stack <?)? Per questioni relative alle stringhe, ho già seguito la guida ai commenti nel file della libreria, che ho inserito ShareMem sia nella clausola first uses della libreria sia nel mio progetto. E ho copiato borlndmm.dll da RAD2010 nella stessa cartella in cui ho provato la DLL usando BDS2006. Non è andato in crash, ma non ha funzionato. Una funzione restituisce una stringa vuota quando nell'ambiente RAD2010 ha funzionato molto bene.Quali principi dovrebbero essere seguiti per far sì che una DLL creata usando Delphi funzioni bene in altre versioni di Delphi?

Ancora una volta, ho una domanda: quali principi dovrebbero essere seguiti per rendere l'incapsulamento di una classe in una DLL compatibile con un'altra versione di Delphi? Grazie in anticipo. (Per incapsulare le funzioni in una DLL quando non si utilizza OOP, non ho rilasciato alcuna altra versione di Delphi).

risposta

8

La definizione di stringa modificata con D2009. Se si desidera rendere sicure le comunicazioni con stringhe, utilizzare un PAnsiChar o un WideString.

La regola di base della comunicazione tramite DLL è di non utilizzare nulla di specifico per Delphi, quindi nessuna stringa Delphi e nessun discendente TObject. Interfacce, record e tipi COM funzionano bene, però.

+4

Vorrei una forte enfasi sul secondo paragrafo. Se non vedi una funzionalità esposta nell'API di Windows, non esporla nemmeno nella tua DLL. Fai finta di scrivere una DLL per essere consumata da C, o anche da un ambiente che non hai mai visto prima. –

+2

+1. Potrebbe anche essere utile sottolineare che non ci dovrebbero (o non devono) esserci tipi specifici di Delphi nei parametri del metodo di interfaccia e nei risultati delle funzioni, né come parti di tali record. – mghie

+1

+1. Forse non correlato, ma non dimenticare di dichiarare tutte le esportazioni di DLL (non COM) come stdcall se le utilizzerai in lingue diverse da Delphi. –

2

vi chiedo:

Ancora una volta, ho una domanda: quali principi dovrebbero essere seguiti al fine di rendere un incapsulamento di una classe in una DLL compatibile con altre versioni di Delphi?

e ce n'è solo uno: non farlo. Tu non puoi farlo. O si scrive una DLL, quindi si usano idiomi e tipi di dati che possono essere tranquillamente usati nelle DLL, il che preclude (tra le altre cose) le classi.

Oppure scrivi una BPL, quindi puoi tranquillamente esportare classi, usare stringhe e così via, ma sei legato alla stessa versione di Delphi. Questa limitazione è di natura tecnica, quindi scrivere una DLL sarà non. Potrebbero esserci trucchi per superare questo problema e potrebbero esserci diverse versioni di Delphi che utilizzano lo stesso layout di classe in modo che funzioni, ma non è necessario legare l'interfaccia DLL pubblica a tali dettagli di implementazione.

2

Stick con solo tipi fondamentali. Se si utilizzano le interfacce, crearle utilizzando l'editor della libreria dei tipi in modo da essere vincolati dai tipi compatibili dall'inizio. Una buona regola è quella di guardare l'API di Windows e provare ad emulare le sue convenzioni di chiamata.

È possibile utilizzare le classi nella DLL, non è possibile esporle come tali. Un buon idioma che funziona bene per le DLL è il concetto di maniglia. La tua DLL crea un oggetto e restituisce un handle per quell'oggetto. Quando è necessario lavorare di nuovo con quell'oggetto, si passa una funzione nella DLL a un handle. Ricorda solo che la tua DLL deve essere completamente responsabile della memoria e della durata dell'oggetto. È un processo banale per creare funzioni DLL per esporre i pezzi della classe che sarà necessario accedere anche.

Dal lato Delphi, è possibile scrivere un wrapper proxy che nasconde l'handle dall'utente. Per gli eventi è possibile utilizzare un metodo di callback.Fondamentalmente si passano i puntatori di funzione non object alla DLL, che quindi richiama la funzione sull'evento. Una rapida panoramica di questo processo è disponibile su Delphi 3000.

+0

Ok notato. Grazie. – WishKnew