Vaikka pointterit varsinaisesti kuuluvat C-kieleen, on myös VB.net:ssä mahdollisuus pointtereiden käyttöön. Palvelut löytyvät Marshal luokasta, joka sijaitsee System.Runtime.InteropServices:ssä.
Osoittimen tyyppi on IntPtr (Dim a as IntPtr).
GCHandle-luokka mahdollista toisen tavan osoittaa muuttujaa, mutta sijoituslause vain siirtää kohdemuuttujan osoittamaan lähdemuuttujaa ja muutokset näkyvät molemmissa!!
Pointterin käyttö:
- Varataan muistia valvomattomalta alueelta(Unmanaged)
- Sirretään data muistiin
- tehdään jotain ....
- Sirretään data takaisin VB muuttujaan.
Luvuille, teksteille ja rakenteille on omat käskynsä.
Taulukoiden siirtoon on Marshal.Copy, jolla siirto tapahtuu mennen-tullen.
Ohjelma esimerkki ei tee mitään, seuraa muuttujien arvoja debuggerilla niin näet toiminnan erot.
Huom! Jos on pakko tehdä C-kielen kanssa yhteensopivia pointtereita, joita siirretään datana (esim rakenteen sisällä) API funktioille, kannattaa muistin varaus ja pointteri tehdä API:n GlobalAlloc funktiolla.
Imports System.Runtime.InteropServices
Public Structure Point
Dim x As Integer
Dim y As Integer
End Structure
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
' Generoitua Koodia poistettu
#End Region
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' tehdään pointteri valvomattomalle muistialueelle,
' jonne data siirretään
' ja luetaan takaisin
Dim pointteri As IntPtr
Dim luku As Integer = 314
'varataan muistia valvotun koodin ulkopuolelta
pointteri = Marshal.AllocHGlobal(4) ' integer on 32 bit = 4 tavua
'kirjoitetaan pointterin osoittamaan muistiin
Marshal.WriteInt32(pointteri, luku)
'luetaan takaisin
Dim toinenLuku As Integer = Marshal.ReadInt32(pointteri)
'
'tekstit ja pointteri
Dim OmaTeksti As String = "Hei siellä"
Dim ptr As IntPtr = Marshal.StringToHGlobalAuto(OmaTeksti)
Dim OmaTEksti2 As String = Marshal.PtrToStringAuto(ptr)
'
'Struktuurit ja pointteri
Dim rakenne1, rakenne2 As Point
rakenne1.x = 100
rakenne1.y = 200
Dim ptr2 As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(rakenne1))
Marshal.StructureToPtr(rakenne1, ptr2, True)
rakenne2 = CType(Marshal.PtrToStructure(ptr2, New Point().GetType), Point) ' Ctype vain koska Option Strict on päällä
'
'Osoitin suoraan (samaan)muuttujaan
Dim gh As GCHandle ' GC = Garbage Collection
Dim emp(10) As Long : emp(1) = 89765
gh = GCHandle.Alloc(emp)
Dim emp2() As Long = CType(gh.Target, Long()) ' Ctype vain koska Option Strict on päällä
emp2(0) = 111 ' myös emp muuttui!!!!
gh.Free() 'muistin vapautus
'
'Taulukon (1D) osoittaminen valvomattomassa muistissa
Dim a(10) As Integer : a(6) = 888
Dim pointteri3 As IntPtr = Marshal.AllocHGlobal(a.Length * 4)
'kopioidaan a:sta muistiin kohtaan pointteri
Marshal.Copy(a, 0, pointteri3, a.Length)
'kopioidaan muistista B:hen
Dim b(10) As Integer
Marshal.Copy(pointteri3, b, 0, a.Length)
b(0) = 99 ' ei vaikuta a:han!!!!!!!!
End Sub
End ClassKiva, että tämäkin on saatu Putkaan.
Tätä kyllä harvemmin tarvitaan. Jos ruvetaan oikein tarkaksi, niin kielenhuollollisesti parempi olisi "osoitin" eikä pointteri.
Pah, pointteri on oikein hyvä, siitä kaikki tietää heti, mitä tarkotetaan.
Niinpä, kauheeta vinetystä kieliopillisesti oikeista käsitteistä :P
Aihe on jo aika vanha, joten et voi enää vastata siihen.