Differenze tra le versioni di "Richiamare funzioni esterne di librerie scritte in C++"

Da Gambas-it.org - Wikipedia.
(Caso in cui viene inviata una stringa alla libreria, da noi creata, e quindi viene da essa ritornata una nuova stringa)
(Caso in cui viene inviata una stringa alla libreria, da noi creata, e quindi viene da essa ritornata una nuova stringa)
Riga 62: Riga 62:
  
 
====Caso in cui viene inviata una stringa alla libreria, da noi creata, e quindi viene da essa ritornata una nuova stringa====
 
====Caso in cui viene inviata una stringa alla libreria, da noi creata, e quindi viene da essa ritornata una nuova stringa====
In questo esempio, invece, poniamo il caso di avere un'unica funzione esterna, rappresentata dalla routine principale ''main()'' del codice C++, la quale riceve e resttitusce per ''riferimento'' una stringa.
+
In questo esempio, invece, poniamo il caso di avere un'unica funzione esterna, rappresentata dalla routine principale ''main()'' del codice C++, la quale riceverà e restituirà per ''riferimento'' una stringa.
  
Anche in questo esempio, ovviamente, tale funzione esterna viene inserita all'interno di un'apposita libreria dinamica .so, che chiameremo ad esempio ''libadhoc.cpp'':
+
Anche in questo esempio, ovviamente, tale funzione esterna viene inserita all'interno di un'apposita libreria dinamica .so (formata dunque da questa sola routine principale), che chiameremo ad esempio ''libadhoc.cpp'':
 
  #include <cstdlib>
 
  #include <cstdlib>
 
  #include <sstream>
 
  #include <sstream>

Versione delle 10:01, 4 mag 2015

Il richiamo con Extern di funzioni esterne presenti in librerie dinamiche .so, scritte in C++, non avviene in Gambas in modo identico alle funzioni esterne scritte in linguaggio C.

Infatti, mentre con le librerie dinamiche .so scritte in C è possibile invocare da Gambas una qualsiasi funzione esterna avente un qualsiasi nome identificatore, con le librerie dinamiche .so scritte in C++ risulta possibile soltanto richiamare la funzione principale, quella vente nome identificatore: main() .

Se la libreria dinamica .so contiene comunque più funzioni, queste dovranno essere chiamate comunque attraverso la funzione principale main(), sia per il motivo sopra esposto, sia perché esse non sono direttamente disponibili all'utente com quelle delle librerie dinamiche .so scritte in C.

Ciò comporta che con Extern non è possibile utilizzare direttamente l'API di librerie esterne dinamiche .so, ma si dovrà creare un'apposita libreria dinamica .so contenente la parte di programma, scritto in C++, che comprende la routine principale main(), nella quale vengono chiamate dal suo codice le funzioni esterne che si intendono utilizzare.

Inoltre, se l'applicazione Gambas è a riga di comando, bisogna prestare attenzione nella dichiarazione con Extern della funzione principale main() dell'apposita libreria esterna dinamica .so, scritta in C++, da noi creata. Infatti, poiché si avrebbero due identificatori sostanzialmente identici "main" (quello della routine principale di Gambas e quello della routine principale dell'apposita libreria esterna scritta in C++), bisognerà attribuire nella dichiarazione un nome fittizio, specificando in fine riga, però, con la parola Exec il nome reale identificatore della funzione principale:

Private Extern Nome_Fittizio(i As Integer, s As String) As Integer in "/percorso/dell'apposita/libreria/esterna" Exec "main"

Il nome fittizio, dunque, può essere un nome qualsiasi.


Esempi pratici

Mostriamo di seguito due semplicissimi esempi pratici.

Caso in cui la libreria da noi creata ritorna un Intero

La funzione in C++ da richiamare sarebbe la seguente:

int Calculus(int n) {

   int c = 100;

   c = n * c;

   return c;

}

che si trova in una certa libreria dinamica .so esterna, chiamata ad esempio libxxx.so

Procediamo nel modo seguente. Creiamo un'apposita libreria dinamica .so esterna, che chiameremo ad esempio libadhoc.cpp:

#include <libxxx.h>


int main(int argc, char *argv[]) {

   int rit;
 
/* Invochiamo la funzione esterna che ci interessa */
   rit = Calculus(argc);

   return rit;

}


Il codice principale del nostro applicativo Gambas a riga di comando sarà il seguente:

Private Extern Cpp_main(i As Integer, p As Pointer) As Integer In "/tmp/libadhoc" Exec "main"


Public Sub Main()

 Dim i As Integer

  i = Cpp_main(4, 0)
 
  Print i

End


Caso in cui viene inviata una stringa alla libreria, da noi creata, e quindi viene da essa ritornata una nuova stringa

In questo esempio, invece, poniamo il caso di avere un'unica funzione esterna, rappresentata dalla routine principale main() del codice C++, la quale riceverà e restituirà per riferimento una stringa.

Anche in questo esempio, ovviamente, tale funzione esterna viene inserita all'interno di un'apposita libreria dinamica .so (formata dunque da questa sola routine principale), che chiameremo ad esempio libadhoc.cpp:

#include <cstdlib>
#include <sstream>
#include <string.h>
 

int main(int c, char *t[]) {

   int i = 0;
   std::string a;
   std::stringstream n;

   if (t[0] == NULL) return -1;

   a = "Aggiunta alla ";

   a = a + t[0];

   *t = strcpy((char*)malloc(a.length()+1), a.c_str());

   return i;

}


Il codice principale del nostro applicativo Gambas a riga di comando sarà il seguente:

Private Extern Cpp_main(i As Integer, p As Pointer) As Integer In "/tmp/libadhoc" Exec "main"

 
Public  Sub Main()

 Dim p As Pointer

  p = Alloc("Stringa inviata")

  i = Cpp_main(0, VarPtr(p))
  If i = -1 Then Error.Raise("Errore !")

  Print "Stringa ritornata:  "; String@(p)

End