Collegamento di funzioni esterne a Proteus |
In questo capitolo forniamo alcune informazioni di carattere tecnico per estendere l'interprete Proteus (versione Windows) aggiungendovi nuove funzioni scritte in Visual C++.
Proteus fornisce un'interfaccia di comunicazione che è illustrata nell'esempio extfunc.prt e che consiste nell'utilizzo di una particolare direttiva:
!extern protfunc, filedll, dllfunc, numpar, dimens
Questa dichiarazione definisce una funzione contenuta in una DLL esterna; prevede sempre cinque parametri:
Parametro Descrizione protfunc stringa che identifica il nome della funzione in Proteus filedll nome della DLL nella quale si trova la funzione dllfunc nome della funzione nella DLL (sensibile alle maiuscole) numpar numero di parametri passati dimens parametro mantenuto per compatibilità; può essere impostato a 0 Nessuna stringa deve essere specificata tra virgolette; esempio:
!extern MessageBox, PROTEXT.DLL, ProteusMessageBox, 3, 0
Nella distribuzione standard, all'interno della cartella Extern, si trova il codice per compilare una DLL di esempio, che permette di richiamare una funzione di sistema (MessageBox), alcune funzioni sulla clipboard di Windows® e altre funzioni contenute in librerie di terze parti, registrate dinamicamente nel codice C++.
Per aggiungere una nuova funzione, modificare il file PROTEXT.CPP dichiarando in questo modo la routine da invocare in Proteus:
void APIENTRY MyFunction(ProtVarExt **parms, int numpar, ProtVarExt *retval)
Modificare, inoltre, il file PROTEXT.DEF, aggiungendo una riga con il nome della funzione esportata ed il suo ordinale preceduto dal carattere "@".
Nel corpo della funzione C++, per ottenere il valore dei diversi parametri si utilizza la chiamata:
int GetVar(ProtVarExt *parm, char **cval, long *lval, double *fval, unsigned int *cval_len)
Questa funzione restituisce una o più rappresentazioni del parametro richiesto, a seconda dei puntatori non nulli specificati dall'utente. I valori stringa sono duplicati e vanno liberati dopo l'uso. Il significato dei vari parametri è il seguente:
Parametro Descrizione parm parametro passato alla funzione da Proteus: parms[0] .. parms[numpar - 1] cval indirizzo di un puntatore a carattere, al quale sarà assegnata una neo-allocata stringa con il valore del parametro richiesto lval indirizzo di un intero lungo, nel quale sarà memorizzata l'interpretazione del parametro fval indirizzo di un numero in virgola mobile a doppia precisione, nel quale sarà memorizzata l'interpretazione del parametro cval_len indirizzo di un intero senza segno, nel quale sarà memorizzata la lunghezza della stringa restituita in cval
Se il primo parametro passato da Proteus è una stringa, il secondo è un intero lungo ed il terzo un valore in virgola mobile, la funzione sarà invocata ripetutamente in questo modo:
char *stringa;
unsigned int lung_stringa;
long num_intero;
double numero;GetVar(parms[0], &stringa, NULL, NULL, &lung_stringa);
GetVar(parms[1], NULL, &num_intero, NULL, NULL);
GetVar(parms[2], NULL, NULL, &numero, NULL);
Per conoscere il tipo di una variabile passata da Proteus, si possono utilizzare le seguenti macro:
Macro Descrizione PROT_LONG(parms[x]) ritorna un valore diverso da zero se il parametro x è di tipo intero lungo PROT_DOUBLE(parms[x]) ritorna un valore diverso da zero se il parametro x è di tipo numero in virgola mobile a precisione doppia PROT_STRING(parms[x]) ritorna un valore diverso da zero se il parametro x è di tipo stringa
Dopo l'elaborazione, la funzione C++ può restituire un valore a Proteus attraverso la seguente chiamata:
void SetVar(ProtVarExt *retval, char *cval, long *lval, double *fval, unsigned int *cval_len)
Questa funzione imposta il valore della variabile retval; solo il primo tra i puntatori non nulli cval, lval e fval viene considerato. Il significato dei vari parametri è il seguente:
Parametro Descrizione retval parametro corrispondente al valore di ritorno (retval negli esempi illustrati) cval puntatore a carattere, contenente la stringa da assegnare lval puntatore ad intero lungo, contenente il valore da assegnare fval puntatore a numero in virgola mobile a doppia precisione, contenente il valore da assegnare cval_len indirizzo di un intero senza segno, contenente la lunghezza della stringa in cval; se non specificato, il numero di bytes copiati in retval corrisponderà a strlen(cval)
La stessa funzione può essere invocata sui parametri parms[0] .. parms[numpar - 1] che, se passati per riferimento, al ritorno acquisiranno il valore assegnato.
La funzione dichiarata in Proteus si può utilizzare come qualsiasi altra funzione.
Inizio pagina | Prossimo argomento | Argomento precedente | Indice per argomenti | Indice analitico |