Differenze tra le versioni di "Utilizzare il metodo 'System.GetExternSymbol()' per richiamare funzioni esterne di librerie condivise"
(Creata pagina con "E' possibile richiamare funzioni esterne di librerie condivise ''.so'' anche senza l'uso di ''Extern'', ma mediante il metodo ".GetExternSymbol()" della Classe ''System'' . I...") |
|||
Riga 1: | Riga 1: | ||
− | E' possibile richiamare funzioni esterne di librerie condivise ''.so'' anche senza l'uso di ''Extern'', ma mediante il | + | E' possibile richiamare funzioni esterne di librerie condivise ''.so'' anche senza l'uso di ''Extern'', ma mediante il Metodo ".GetExternSymbol()" della Classe ''System'' . |
In tal caso la procedura è più complessa. Infatti, poiché si farà uso di un [[Scrivere_una_libreria_esterna_che_chiama_una_funzione_esterna_puntata|puntatore alla funzione esterna]] da invocare ed utilizzare, sarà necessario creare una nostra apposita libreria ''ad hoc'', nella quale si chiamerà effettivamente la funzione esterna. | In tal caso la procedura è più complessa. Infatti, poiché si farà uso di un [[Scrivere_una_libreria_esterna_che_chiama_una_funzione_esterna_puntata|puntatore alla funzione esterna]] da invocare ed utilizzare, sarà necessario creare una nostra apposita libreria ''ad hoc'', nella quale si chiamerà effettivamente la funzione esterna. | ||
− | Mostriamo di seguito un esempio, nel quale supponiamo di dover invocare una funzione che svolge una semplice moltiplicazione utilizzando il valore ricevuto dal nostro progetto Gambas. Tale funzione esterna, che chiameremo | + | Mostriamo di seguito un esempio, nel quale supponiamo di dover invocare una funzione che svolge una semplice moltiplicazione utilizzando il valore ricevuto dal nostro progetto Gambas. Tale funzione esterna, che chiameremo "FunzioneEsterna()", è contenuta in una libreria esterna, il cui file sorgente chiameremo LibreriaEsterna.c, il cui semplice codice sorgente in C è il seguente: <SUP>[[[#Note|nota 1]]]</sup> |
int FunzioneEsterna(int i) { | int FunzioneEsterna(int i) { | ||
Riga 11: | Riga 11: | ||
} | } | ||
− | Il codice del progetto Gambas sarà il seguente: | + | Il codice del progetto Gambas invece sarà il seguente: |
Private Extern Invoca_Funzione(fun_est As Pointer, valore As Integer) As Integer In "/tmp/Libadhoc" | Private Extern Invoca_Funzione(fun_est As Pointer, valore As Integer) As Integer In "/tmp/Libadhoc" | ||
− | + | Public Sub Main() | |
Dim libreriaso As String = "/tmp/LibreriaEsterna.so" | Dim libreriaso As String = "/tmp/LibreriaEsterna.so" | ||
Riga 34: | Riga 34: | ||
Print "Risultato: "; ris | Print "Risultato: "; ris | ||
− | + | End | |
− | + | Private Procedure CreaLibSoAdHoc() | |
<FONT Color=gray>' ''Imposta il codice C della libreria ad hoc da creare:''</font> | <FONT Color=gray>' ''Imposta il codice C della libreria ad hoc da creare:''</font> | ||
Riga 44: | Riga 44: | ||
Shell "gcc -o /tmp/Libadhoc.so /tmp/Libadhoc.c -shared" Wait | Shell "gcc -o /tmp/Libadhoc.so /tmp/Libadhoc.c -shared" Wait | ||
− | + | End | |
Come si è potuto notare, la parola chiave ''Extern'' è stata comunque utilizzata, anche se però non direttamente per dichiarare la vera funzione esterna da chiamare e da utilizzare (ossia quella contenuta in ''LibreriaEsterna.c''), ma solo per dichiarare la funzione esterna della libreria ''ad hoc'' da noi creata che provvede ad invocare ed utilizzare la predetta funzione esterna di ''LibreriaEsterna.c''. | Come si è potuto notare, la parola chiave ''Extern'' è stata comunque utilizzata, anche se però non direttamente per dichiarare la vera funzione esterna da chiamare e da utilizzare (ossia quella contenuta in ''LibreriaEsterna.c''), ma solo per dichiarare la funzione esterna della libreria ''ad hoc'' da noi creata che provvede ad invocare ed utilizzare la predetta funzione esterna di ''LibreriaEsterna.c''. | ||
====Esempio con una funzione esterna della libreria standard di C==== | ====Esempio con una funzione esterna della libreria standard di C==== | ||
− | In quest'altro esempio utilizzeremo in modo semplice la funzione esterna | + | In quest'altro esempio utilizzeremo in modo semplice la funzione esterna "'printf()", dichiarata nel file header ''/usr/include/stdio.h''. |
Private Extern Invoca_Funzione(FunzioneEsternaPuntata As Pointer) As Integer In "/tmp/libso" | Private Extern Invoca_Funzione(FunzioneEsternaPuntata As Pointer) As Integer In "/tmp/libso" | ||
− | + | Public Sub Main() | |
Dim p As Pointer | Dim p As Pointer | ||
Riga 66: | Riga 66: | ||
Invoca_Funzione(p) | Invoca_Funzione(p) | ||
− | + | End | |
− | + | Private Procedure CreaSo() | |
<FONT Color=gray>' ''Scrive e salva il sorgente della nostra libreria esterna ad hoc dinamica condivisa per la chiamata della funzione puntata "printf()":''</font> | <FONT Color=gray>' ''Scrive e salva il sorgente della nostra libreria esterna ad hoc dinamica condivisa per la chiamata della funzione puntata "printf()":''</font> | ||
Riga 77: | Riga 77: | ||
Shell "gcc -o /tmp/libso.so /tmp/libso.c -shared -fPIC" Wait | Shell "gcc -o /tmp/libso.so /tmp/libso.c -shared -fPIC" Wait | ||
− | + | End | |
Di seguito vediamo un esempio simile al precedente, ma ora passando dei valori agli argomenti della funzione esterna "printf()". | Di seguito vediamo un esempio simile al precedente, ma ora passando dei valori agli argomenti della funzione esterna "printf()". | ||
Private Extern Invoca_Funzione(FunzioneEsternaPuntata As Pointer, st As String) As Integer In "/tmp/libso" | Private Extern Invoca_Funzione(FunzioneEsternaPuntata As Pointer, st As String) As Integer In "/tmp/libso" | ||
− | + | Public Sub Main() | |
Dim p As Pointer | Dim p As Pointer | ||
Riga 95: | Riga 95: | ||
Invoca_Funzione(p, "abcdefg") | Invoca_Funzione(p, "abcdefg") | ||
− | + | End | |
− | + | Private Procedure CreaSo() | |
<FONT Color=gray>' ''Nella funzione puntata vanno descritti i parametri previsti dalla funzione esterna "printf()":''</font> | <FONT Color=gray>' ''Nella funzione puntata vanno descritti i parametri previsti dalla funzione esterna "printf()":''</font> | ||
Riga 106: | Riga 106: | ||
Shell "gcc -o /tmp/libso.so /tmp/libso.c -shared -fPIC" Wait | Shell "gcc -o /tmp/libso.so /tmp/libso.c -shared -fPIC" Wait | ||
− | + | End | |
=Note= | =Note= | ||
− | Se si intende provare l'esempio pratico esposto in questa pagina, il codice sorgente della libreria esterna ''LibreriaEsterna.c'' va compilato nel terminale con la seguente riga di comando: | + | [1] Se si intende provare l'esempio pratico esposto in questa pagina, il codice sorgente della libreria esterna ''LibreriaEsterna.c'' va compilato nel terminale con la seguente riga di comando: |
~ $ gcc -o /tmp/LibreriaEsterna.so /tmp/LibreriaEsterna.c -shared | ~ $ gcc -o /tmp/LibreriaEsterna.so /tmp/LibreriaEsterna.c -shared |
Versione attuale delle 08:57, 11 giu 2023
E' possibile richiamare funzioni esterne di librerie condivise .so anche senza l'uso di Extern, ma mediante il Metodo ".GetExternSymbol()" della Classe System .
In tal caso la procedura è più complessa. Infatti, poiché si farà uso di un puntatore alla funzione esterna da invocare ed utilizzare, sarà necessario creare una nostra apposita libreria ad hoc, nella quale si chiamerà effettivamente la funzione esterna.
Mostriamo di seguito un esempio, nel quale supponiamo di dover invocare una funzione che svolge una semplice moltiplicazione utilizzando il valore ricevuto dal nostro progetto Gambas. Tale funzione esterna, che chiameremo "FunzioneEsterna()", è contenuta in una libreria esterna, il cui file sorgente chiameremo LibreriaEsterna.c, il cui semplice codice sorgente in C è il seguente: [nota 1]
int FunzioneEsterna(int i) { i = i * 10; return i; }
Il codice del progetto Gambas invece sarà il seguente:
Private Extern Invoca_Funzione(fun_est As Pointer, valore As Integer) As Integer In "/tmp/Libadhoc" Public Sub Main() Dim libreriaso As String = "/tmp/LibreriaEsterna.so" Dim NomeFunzione As String = "FunzioneEsterna" Dim p As Pointer Dim ris As Integer ' Carica la funzione esportata da 'mialibreria.so': p = System.GetExternSymbol(Replace(libreriaso, ".so", Null), NomeFunzione) If p == 0 Then Error.Raise("Impossibile caricare la funzione della libreria esterna !") ' Crea un'apposita libreria condivisa esterna ".so", il cui file del codice sorgente sarà chiamato "Libadhoc.c": CreaLibSoAdHoc() ' Invoca la 'FunzioneEsterna' e le passa un Intero: ris = Invoca_Funzione(FunzioneEsterna, 44) Print "Risultato: "; ris End Private Procedure CreaLibSoAdHoc() ' Imposta il codice C della libreria ad hoc da creare: File.Save("/tmp/Libadhoc.c", "int Invoca_Funzione(int (*FunzioneEsterna)(int), int r) {\n" & " return FunzioneEsterna(r); \n}") Shell "gcc -o /tmp/Libadhoc.so /tmp/Libadhoc.c -shared" Wait End
Come si è potuto notare, la parola chiave Extern è stata comunque utilizzata, anche se però non direttamente per dichiarare la vera funzione esterna da chiamare e da utilizzare (ossia quella contenuta in LibreriaEsterna.c), ma solo per dichiarare la funzione esterna della libreria ad hoc da noi creata che provvede ad invocare ed utilizzare la predetta funzione esterna di LibreriaEsterna.c.
Esempio con una funzione esterna della libreria standard di C
In quest'altro esempio utilizzeremo in modo semplice la funzione esterna "'printf()", dichiarata nel file header /usr/include/stdio.h.
Private Extern Invoca_Funzione(FunzioneEsternaPuntata As Pointer) As Integer In "/tmp/libso" Public Sub Main() Dim p As Pointer ' Invoca la procedura per scrivere il sorgente e per creare la libreria dinamica condivisa: CreaSo() ' Richiama mediante System.GetExternSymbol() la funzione "printf()" della libreria standard di C: p = System.GetExternSymbol("libc:6", "printf") ' Invoca la funzione esterna da noi creata e le passiamo il Puntatore alla funzione esterna "printf()": Invoca_Funzione(p) End Private Procedure CreaSo() ' Scrive e salva il sorgente della nostra libreria esterna ad hoc dinamica condivisa per la chiamata della funzione puntata "printf()": File.Save("/tmp/libso.c", "void Invoca_Funzione(int (*FunzioneEsternaPuntata)(const char *__restrict __format)) {\n\n" & " FunzioneEsternaPuntata(\"abcdefg\");\n\n}") ' Crea la nostra libreria esterna dinamica condivisa ad hoc: Shell "gcc -o /tmp/libso.so /tmp/libso.c -shared -fPIC" Wait End
Di seguito vediamo un esempio simile al precedente, ma ora passando dei valori agli argomenti della funzione esterna "printf()".
Private Extern Invoca_Funzione(FunzioneEsternaPuntata As Pointer, st As String) As Integer In "/tmp/libso" Public Sub Main() Dim p As Pointer ' Invoca la procedura per scrivere il sorgente e per creare la libreria dinamica condivisa: CreaSo() ' Richiama mediante System.GetExternSymbol() la funzione "printf()" della libreria standard di C: p = System.GetExternSymbol("libc:6", "printf") ' Invoca la funzione esterna da noi creata e le passiamo il Puntatore alla funzione esterna "printf()": Invoca_Funzione(p, "abcdefg") End Private Procedure CreaSo() ' Nella funzione puntata vanno descritti i parametri previsti dalla funzione esterna "printf()": File.Save("/tmp/libso.c", "void Invoca_Funzione(int (*FunzioneEsternaPuntata)(const char *__restrict __format, char * stringa), char * st) {\n\n" & " FunzioneEsternaPuntata(\"%s\\n\", st); \n\n}") ' Crea la nostra libreria esterna dinamica condivisa ad hoc: Shell "gcc -o /tmp/libso.so /tmp/libso.c -shared -fPIC" Wait End
Note
[1] Se si intende provare l'esempio pratico esposto in questa pagina, il codice sorgente della libreria esterna LibreriaEsterna.c va compilato nel terminale con la seguente riga di comando:
~ $ gcc -o /tmp/LibreriaEsterna.so /tmp/LibreriaEsterna.c -shared