Mi faresti cortesemente lo stesso esempio ma con codice Gambas 3?
...dunque.... vediamo (con qualche nome cambiato):
Public Sub Button1_Click() ' al clic si scatena... l'inferno !
Dim a, b As Integer
Dim aP, bP As Pointer
' i valori Integer di partenza sono:
a = 10
b = 20
' ...e li mostriamo in console:
Print "a iniziale = "; a, "b iniziale = "; b
' poniamo due puntatori in memoria alle due variabili Integer.
' ap e bP non contengono gli interi, bensi gli indirizzi di memoria ove andare a "raccogliere" i due valori Integer:
aP = VarPtr(a)
bP = VarPtr(b)
' passiamo i valori pointer alla subroutine "swp":
swp(aP, bP)
End
Public Sub swp(aPoi As Pointer, bPoi As Pointer)
Dim aStream, bStream As Stream
Dim tempus, aInt, bInt, a, b As Integer
Dim bTerPointer As Pointer
' dereferenziamo il pointer mediante l'uso dei Memory-Stream:
aStream = Memory aPoi For Read
' e lo andiamo a leggere:
Read #aStream, aInt
' l'intero viene trasferito nella variabile Integer "tempus",
' (nel tuo esempio in C siamo al punto: temp=*a; ):
tempus = aInt
aPoi = bPoi ' (qui siamo al punto: *a=*b; )
' dereferenziamo nuovamente il pointer aPoi,
' (ma questa volta senza Memory-Stream,
' bensì con l'apposita funzione " Int@ ")
' ci servirà per la verifica finale:
aInt = Int@(aPoi)
bTerPointer = VarPtr(tempus) ' (qui siamo al punto: *b=temp; )
'dereferenziamo l'altro pointer per la verifica finale:
bInt = Int@(bTerPointer)
a = aInt
b = bInt
' verifichiamo l'inversione, mostrandola in console:
Print "a finale = "; a, "b finale = "; b
End
....alla fine ho coerentemente i valori invertiti.
Se vuoi utilizzare una Funzione (come è nell'esempio originario in C ), e - come hai detto -
non vuoi usare variabili
globali, allora si potrebbe fare così:
Public Sub Button1_Click()
Dim a, b As Integer
Dim aP, bP As Pointer
Dim abPoi As Pointer[]
Dim aStream, bStream As Stream
' i valori Integer di partenza sono:
a = 10
b = 20
' ...e li mostriamo in console:
Print "a iniziale = "; a, "b iniziale = "; b
' poniamo due puntatori in memoria alle due variabili Integer.
' ap e bP non contengono gli interi, bensi gli indirizzi di memoria ove andare a "raccogliere" i due valori Integer:
aP = VarPtr(a)
bP = VarPtr(b)
' Passiamo i valori pointer alla Funzione "swp", affinché li elabori.
' La variabile "abPoi" conterrà i valori di elaborazione ritornati da quella Funzione:
abPoi = swp(aP, bP)
' dereferenziamo mediante l'uso dei Memory-Stream il primo pointer,
' restituito dalla Funzione, per la verifica finale:
aStream = Memory abPoi[0] For Read
' e lo andiamo a leggere:
Read #aStream, a
' dereferenziamo il secondo pointer, restituito dalla Funzione, per la verifica finale,
' questa volta però con la funzione specifica " Int@ " :
b = Int@(abPoi[1])
' verifichiamo l'inversione, mostrandola in console:
Print "a finale = "; a, "b finale = "; b
End
Public Function swp(aPoi As Pointer, bPoi As Pointer) As Pointer[]
Dim aStream, bStream As Stream
Dim tempus, aInt, bInt, a, b As Integer
Dim bTerPointer As Pointer
Dim doppioPoin As New Pointer[]
' dereferenziamo il pointer mediante l'uso dei Memory-Stream:
aStream = Memory aPoi For Read
' e lo andiamo a leggere:
Read #aStream, aInt
' l'intero viene trasferito nella variabile Integer "tempus",
' (nel tuo esempio in C siamo al punto: temp=*a; ):
tempus = aInt
aPoi = bPoi ' (qui siamo al punto: *a=*b; )
bTerPointer = VarPtr(tempus) ' (qui siamo al punto: *b=temp; )
doppioPoin.Add(aPoi)
doppioPoin[0] = aPoi
doppioPoin.Add(bTerPointer)
doppioPoin[1] = bTerPointer
' restituiamo i due valori Pointer, contenuti in doppioPoin, alla routine principale chiamante:
Return doppioPoin
End
....alla fine ho coerentemente i valori invertiti.
Ah, scusami, riguardo invece al tuo esempio iniziale:
Public Sub Button8_Click()
Dim iDatiElaborati As Integer
Dim datiPntr As Pointer
iDatiElaborati = 2
' mostriamo il valore Integer di partenza
Print iDatiElaborati
' poniamo nel pointer "datiPntr" l'indirizzo che punta alla variabile Integer "iDatiElaborati":
datiPntr = VarPtr(iDatiElaborati)
' passiamo alla routine del modulo l'indirizzo contenuto nel Pointer:
MDB_DBDati.wow(datiPntr)
End
Public Sub wow(idP As Pointer) ' qui siamo nel MODULO: MDB_DBDati
Dim a, iDatiElaborati As Integer
Dim aStream As Stream
' dereferenziamo il pointer con l'uso di specifica funzione:
iDatiElaborati = Int@(idP)
' verifichiamo (avremo coerentemente l'intero di partenza),
' e lo mostriamo in console:
Print "1° valore nel modulo = "; iDatiElaborati
' ...poi tu hai voluto caricare nella variabile Integer un altro valore:
iDatiElaborati = 100
' e lo mostriamo in console:
Print "2° valore nel modulo = "; iDatiElaborati
End
In sostanza, dopo aver posto con
VarPtr in un
puntatore l'indirizzo di una variabile, per
estrarre il valore contenuto nella variabile puntata dal puntatore, ossia per
deferenziare il pointer puoi usare i
Memory-Stream (soprattutto se è stata utilizzata una zona riservata di memoria con la funzione
alloc) in lettura, oppure più brevemente una specifica funzione (
Int@,
Byte@,
Float@, etc, a seconda del tipo ovviamente) che restituisca il valore memorizzato all'indirizzo specificato dal Puntatore.
Sui
puntatori vedere anche qui:
http://www.gambas-it.org/smf/index.php?topic=586.0http://www.gambas-it.org/wiki/index.php/Variabili_di_tipo_Puntatore_e_loro_dereferenziazione