Newsgroup: it.comp.lang.delphi
Titolo: DLL e "Opaque structure"

Delphi 4 Win98 SE
Sto tentando di utilizzare una DLL.
Ho un esempio in C che sto passando in Delphi per fare delle prove (mai
comperare a scatola chiusa, neppure le DLL).
Per caricare la DLL uso
 LibHandle := LoadLibrary( 'XpdfPrint.dll' );
 if ( LibHandle <> 0 ) then
   begin
  @pdfInitLibrary := GetProcAddress( LibHandle, 'pdfInitLibrary' );
  @pdfLoadFile := GetProcAddress( LibHandle, 'pdfLoadFile' );
  @pdfLibraryVersion := GetProcAddress( LibHandle, 'pdfLibraryVersion' );
  Caption := pdfLibraryVersion;
  end;
con
type
 TpdfInitLibrary = function( configFileName: PChar ): THandle; stdcall;
 TpdfLoadFile = procedure( pdfPtr: Pointer; pdfFileName: pchar ); stdcall;
 TpdfLibraryVersion = function: PChar;
  LibHandle: THandle;
  pdfInitLibrary: TpdfInitLibrary;
  pdfLoadFile: TpdfLoadFile;
  pdfLibraryVersion: TpdfLibraryVersion;
Il codice in C dice:
  pdfLoadFile(&pdf, "nome_del_file_pdf" );
dove
 typedef struct _PDFHandle *PDFHandle;
  PDFHandle pdf;
 LIBFUNC int pdfLoadFile(PDFHandle *pdfPtr, char *pdfFileName);
Il problema dov'è ?
Il problema sta nel fatto che NON conosco come è "struct _PDFHandle" per cui
non riesco a creare il record equivalente.
Domandando al servizio di support delucidazioni, mi hanno detto che non mi
deve einteressare com'è questo tipo di variabile in quanto è una struttura
interna della DLL, si tratta di Opaque structure.
Io ho provato ad usare un banalissimo Pointer, ma mi dà un errore di ACCESS
VIOLATION.
Sinceramente non so cosa devo creare o cosa sto sbagliando.
Se qualcuno può darmi una mano...
Se desiderate maggior codice ...
Grazzzzie
Andrea

 Io ho provato ad usare un banalissimo Pointer, ma mi dà un errore di
Il fatto è che quando chiamano
  pdfLoadFile(&pdf, "nome_del_file_pdf" );
passano l'indirizzo del puntatore, quindi la tua chiamata dovrebbe essere
così
var
  p: pointer;
begin
...
  pdfLoadFile(@p, 'nome_del_file_pdf');
HTH :-)
--
Andrea /\/\agni
ICQ#: 174108000

   pdfLoadFile(@p, 'nome_del_file_pdf');
Ho provato e mi chiude direttamente l'applicazione.
Mi sto chiedendo se, per caso, il primo parametro non sia un var ... arig di
logica direi di sě visto che in C per definisce un parametro "in uscita"
(scusa il termine poco informatico ...) si lavora di puntatori.
Che ne dici ?
Andrea

Domanda idiota: per caso mi sono dimenticato di creare qualcosa ?

(scusa il termine poco informatico ...) si lavora di puntatori.
In realtà è un puntatore a puntatore, nel senso che stai passando per
riferimento (e non per valore) un puntatore.  Questo significa che,
probabilmente, la funzione alloca memoria e la assegna al puntatore.
Mi spiego:
Se in C io scrivo (non ho compilato):
#include <stdlib.h>
void imalloc(int *p)
{
     p = malloc(100);
}
int main()
{
    int *p;
    imalloc(p);
}
Sto passando il puntatore per valore e sto commettendo un errore
logico.  Se invece scrivo:
#include <stdlib.h>
void imalloc(int **p)
{
     *p = malloc(100);
}
int main()
{
    int *p;
    imalloc(&p);
}
Sto passando il puntatore per riferimento e sto facendo,
correttamente, un'allocazione e un'assegnazione del nuovo indirizzo di
memoria al puntatore del main() tramite la funzione imalloc.

 probabilmente, la funzione alloca memoria e la assegna al puntatore.
Comincio a far confusione.
Io sono di estrazione C e sicuramente i parametri che in Delphi sono var in
C devono essere passsati per riferimento e non per valore (in C non esiste
il var).
Quello che mi domandavo e credo sia corretto per logica, è se non ho
sbagliato io a trasformare la dichiarazione
int pdfLoadFile(PDFHandle *pdfPtr, char *pdfFileName);
in
function pdfLoadFile( var pdfPtr: pointer; pdfFileName: PChar);
Ciao
PS
Anche facendo così ho semrpe l'errore di allocazione, ergo nno ci capisco
nulla :'((((((((((((((

function pdfLoadFile( var pdfPtr: pointer; pdfFileName: PChar);
Per logica non č corretto.  Questa seconda traduzione corrisponde a:
int pdfLoadFile(PDFHandle **pdfPtr, char *pdfFileName);
La traduzione corretta č:
function pdfLoadFile(pdfPtr: pointer; pdfFileName: PChar);
In realtą la traduzione corretta vorrebbe che pdfPtr fosse un
puntatore a PDFHandle, con PDFHandle definita in qualche modo.

 puntatore a PDFHandle, con PDFHandle definita in qualche modo.
La traduzione corretta non riesco a farla visto che non mi danno la
struttura.
Sto giocando con tutte le combinazioni (anche senza var) ma ottengo semrpe
Access Violation: hai qualche suggerimento ?
Grazie

struttura.
Se non ti danno la struttura di partenza, difficilmente ci potrai fare
qualcosa.  Molte API Windows, ad esempio, richiedono la corretta
impostazione di un campo della struttura che viene loro passata, per
funzionare correttamente.

 Domanda idiota: per caso mi sono dimenticato di creare qualcosa ?
Non mi sembra.
Piuttosto avrei un altro dubbio:
Se, riprendendo un attimo il codice che ti ho scritto prima:
var
  p: pointer;
begin
...
  pdfLoadFile(@p, 'nome_del_file_pdf');
lo fai in una procedura, all'uscita della procedura la variabile p viene
deallocata.
Tu fai tutte le elaborazioni in un'unica procedura o in più procedure
separate? Nel primo caso allora il problema è altrove (le convenzioni di
chiamata?), nel secondo non va bene!
Ciao
