Toon posts:

[VB6] pointers in VB, kan waarde niet achterhalen

Pagina: 1
Acties:
  • 152 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik ben bezig met een progje dat een ingeladen wav file afspeelt. Omdat ik tijdens het afspelen realtime een filter wil toepassen, wordt de wave in 2 kleine buffertjes opgedeeld die omdebeurt via WaveOutWrite worden afgespeeld. Details zijn verder niet zo relevant, het werkt prima tot zover.

Het probleem is nu dat waveoutwrite etc. (API calls) werken met de pointer die naar de eigenlijke data verwijst. Deze data is niets anders dan een array van integers (16 bit wave).
code:
1
2
3
4
5
6
7
8
'Pointer naar wavedata declareren
Dim bufferIn As Long
....
' Allocate soundbuffer and read sound data
GlobalFree hmem
hmem = GlobalAlloc(&H40, mmckinfoSubchunkIn.ckSize)
bufferIn = GlobalLock(hmem)
rc = mmioRead(hmmioIn, bufferIn, mmckinfoSubchunkIn.ckSize)


Ik heb dus de beschikking over de pointer naar de wave data. Ik kan de data opdelen door WAVEHEADERS te definieren die naar kleine 'chunks' van de data wijzen door relatief aan de pointer te refereren (BufferIn + 256 bijvoorbeeld)
Wat ik echter NIET kan is direct bij de data zelf komen! Ik zou natuurlijk een volledige kopie (of iedere keer fragmentjes van een aantal kbytes) van de data kunnen maken met
CopyStructFromPtr

maar dat vind ik geen mooie oplossing omdat de data al aanwezig is. In C++ kun je simpel de-referencen, maar in VB lukt me dat dus niet. Heb lang gezocht, mooie artikels gevonden over pointers etc maar nou juist niet hetgene ik wil. (Een mooie pagina is http://www.thevbzone.com/secrets.htm , MSDN: http://support.microsoft....spx?scid=kb;en-us;Q199824

Weet iemand hoe ik direct over de data achter die bufferIn pointer kan beschikken?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-08 18:33
Het spijt me zeer maar wat is je overweging geweest om VB te kiezen bij dit project ?

Het is er duidelijk niet geschikt voor; je code zit vol API calls ( GlobalAlloc( ... ) notabene ) en je wil met pointers werken.

Als het je om de formuliertjes gaat, C++ builder bv kan er ook wat van hoor.

Verder geen echt nuttige info van mijn kant ..... ;)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
Hehe had zo'n reply niet meteen verwacht, maar je hebt op zich wel gelijk natuurlijk. De reden is gewoon dat je met VB 'snel' iets in elkaar kunt draaien. Ik ben ook pas net begonnen met C++ (MFC) en wilde gewoon snel iets werkbaars hebben. Het is zeker wel de bedoeling om een vervolg te maken in (visual) c++.

Ik heb ondertussen een ander probleem: het filter werkt nu realtime, je kunt met een slider op het form de cutt-off frequentie en resonantie in stellen. Echter, zodra ik met de muis het slider op de form aanpas, lijkt deze control alle processor tijd te krijgen zodat de playback even stopt. Als ik de slider eerst selecteer en dan met de pijltjes op het toetsenbord de slider verplaats is er geen hapering.
Typisch VB probleem of kan ik het omzeilen?

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 18-08 22:57

Gerco

Professional Newbie

VB gebruikt maar 1 thread en als die thread bezig is met de slider verplaatsen (zoals hij is als je 'em met de muis pakt), dan kan 'ie niet jouw wave-afspeel code draaien (timer ofzo?). De oplossing hiervoor zou dus zijn een tweede thread die de wave afspeelt en eigenlijk nog een derde die de filter toepast.

Alleen heeft VB standaard geen threading support, het KAN wel een beetje met CreateThread(), maar het is verre van ideaal en al helemaal niet iets in de buurt van veilig of stabiel (aangezien de vb runtime niet thread safe is).

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Klopt, wat ook zo lekker is, is dat de 'preview' van je app onder hetzelfde proces draait als die van VB zelf. Loopt je proggie vast? Vergeten te saven? Dikke pech!

Maargoed, zover ik weet is in VB idd de enige manier om bij die data te komen CopyMemory :|

[ Voor 26% gewijzigd door Verwijderd op 31-08-2003 22:11 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-08 18:33
Naja, weer een reden om je prototype ook in C++ te maken .... :)

( Echt, als je het onder de knie hebt gaat het ( bijna ) net zo snel als in VB )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 15-08 11:47

Sponge

Serious Game Developer

farlane schreef op 31 August 2003 @ 22:40:
Naja, weer een reden om je prototype ook in C++ te maken .... :)

( Echt, als je het onder de knie hebt gaat het ( bijna ) net zo snel als in VB )
imo, als je de API's en de programmeer style wat VB graag wilt zien (dus denken om \'s en '/s, gee nvarianten e.d.) dan is VB gewoon net zo lekker werkend als C++

Een timer heeft trouwens z'n eigen thread, dit kan je proberen. op www.pscode.com stana ook voorbeelden die threading relatief "safe" maken. Misschien iets om naar te kijken.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-08 18:33
41.6C.6D.61.72 schreef op 31 augustus 2003 @ 22:44:
[...]
imo, als je de API's en de programmeer style wat VB graag wilt zien (dus denken om \'s en '/s, gee nvarianten e.d.) dan is VB gewoon net zo lekker werkend als C++
Begrijp me niet verkeerd, ik doe behoorlijk vaak wat met VB en het heeft zo zijn toepassingen. Ik merk echter steeds vaker dat als je aan onderhoudbare appliatie wilt schrijven ( zon applicatie die niet uit alleen pukkels bestaat ;) ) je met VB ook behoorlijk lang bezig bent. En dan heb je de code volstaan met API calls en ActiveX controls.
Ik vraag me dan altijd af of het niet handiger is om iets meer tijd te besteden aan het in elkaar zetten van de user interface en zo een robuuster applicatie af te leveren.
Een timer heeft trouwens z'n eigen thread, dit kan je proberen. op www.pscode.com stana ook voorbeelden die threading relatief "safe" maken. Misschien iets om naar te kijken.
Volgens mij zijn timers gebaseerd op de windows timers die een message posten naar je formulier window. Die draaien naar mijn weten niet in een andere thread.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
Bedankt voor de reply's. Weer wat geleerd over threading. IDD, als mijn progje crasht dan crash VB ook en vice versa. Ik heb het probleem van die slider trouwens opgelost met een picture box, dat werkt in mijn geval nog 'chiquer' ook. Ik heb namelijk 2 sliders waarbij de een de resonantie aanstuurt en de andere de cut-off frequentie. Door nu met je muis over de picture box te bewegen krijg je via de mouse-move event gewoon een x en een y coordinaat. Die link ik aan resonantie en frequentie (en aan de sliders) en dat geeft dus absoluut geen hapering.

Ik vind het toch raar dat ik niet bij de data kan komen waarnaar de pointer verwijst. Ik moet nu een kopie maken van de wave file, en dat is natuurlijk niet efficient bij grotere waves (>1MB enzo).
Het probleem is nu ook dat ik, omdat ik vantevoren weet hoe groot de wave file gaat zijn, ik een integer array aanmaak met 500.000 (!) plaatsen. Dit zou natuurlijk afhankelijk moeten zijn van de grootte van de sample.
Is er misschien de mogelijkheid om een array te declareren met
Dim sample() as integer
dus nog niet de grootte opgegegen, en dan de pointer van deze array aan te passen aan de pointer van de originele sample?
Dus iets van VarPtr(sample(1)) = BufferIn
(wat niet kan op deze manier...)

Als iemand geinteresseerd is in het progje kan ik 'm wel ergens neerzetten.

  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 15-08 11:47

Sponge

Serious Game Developer

Dynamische array bedoel je?

Dim Samples() as integer en ergens anders Redim Samples(hoeveelheid).

Overigens, misschien is DirectSound van directx nog een idee? :) misschien kom je daar wel makkelijker bij de bytedata. Op www.pscode.com staan er zelfs een paar tracker format spelers op die direct de bytes gebruiken oid..

Verwijderd

DirectSound geeft betere performance [werkt ook goed met kleine buffers] en is werkelijk zo simpel aan te sturen. Kan bijna niet fout meer gaan

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
Voorbeeldcode gemaakt en getest in VBA, zal ook wel in VB werken.

Het veranderen van de array info is niet compleet, maar het werkt wel een beetje, maar bijv. het lokale variabelen venster geeft niet weer dat er meer elementen zijn. Array moet base 0 zijn. Ook moet de grootte van de elementen overeenkomen met wat je uiteindelijk wilt.

Als je meer wilt mag je zelf debuggen.

In plaats van strptr(str) de pointer naar je data gebruiken, in in plaats van len(str) * 2 + 2 het aantal elementen van de nieuwe array, dus x bytes of x integers of wat voor type array je ook hebt.

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() As Any) As Long
Private Declare Sub GetMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, RetVal As Long)
Private Declare Sub PutMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, ByVal NewVal As Long)

Private Type arrayinfo
    infoptr As Long     'pointer naar type info van array
    dataptr As Long     'pointer naar data
    length As Long        'aantal elementen in deze array
End Type

Private Sub Knop1_Click()
    Dim temp(0) As Byte
    Dim arrayinfo As arrayinfo
    
'oude data opslaan, voor cleanup misschien belangrijk
    GetMem4 VarPtrArray(temp()), arrayinfo.infoptr
    GetMem4 arrayinfo.infoptr + 12, arrayinfo.dataptr
    GetMem4 arrayinfo.infoptr + 16, arrayinfo.length

'nieuwe data invoeren
    Dim str As String
    str = "blahblah"
    PutMem4 arrayinfo.infoptr + 12, StrPtr(str)
    PutMem4 arrayinfo.infoptr + 16, len(str) * 2 + 2 'unicode neemt twee bytes per char, en terminating 0
    
    Dim x As Integer
    For x = 0 To 17
        Debug.Print temp(x) & " " & Chr(temp(x))
    Next x

'oude data terugzetten
    PutMem4 arrayinfo.infoptr + 12, arrayinfo.dataptr
    PutMem4 arrayinfo.infoptr + 16, arrayinfo.length
End Sub

[ Voor 5% gewijzigd door _js_ op 03-09-2003 08:25 . Reden: Long->Byte, code werkt nu als bedoelt. ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-08 18:33
Visual Basic:
1
2
3
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() As Any) As Long
Private Declare Sub GetMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, RetVal As Long)
Private Declare Sub PutMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, ByVal NewVal As Long)
Ligt het aan mij of ben ik de enige die hier een beetje bang van wordt ?

Als ik het goed begrijp gebruik je hier ongedocumenteerde functies uit de VB runtime om geheugen heen en weer te gooien ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 13:39

johnwoo

3S-GTE

farlane schreef op 31 August 2003 @ 19:11:
Het spijt me zeer maar wat is je overweging geweest om VB te kiezen bij dit project ?

Het is er duidelijk niet geschikt voor; je code zit vol API calls ( GlobalAlloc( ... ) notabene ) en je wil met pointers werken.

Als het je om de formuliertjes gaat, C++ builder bv kan er ook wat van hoor.

Verder geen echt nuttige info van mijn kant ..... ;)
VB en de Win32 API gaan prima samen hoor, het gebruik van Win32 is niet voor niets zo eenvoudig in VB :) En over code vol API calls: wel eens een Win32 app in C gezien zonder API calls? :P VB is veel schoner van calls dan C. Overigens zuigt malloc() het geheugen ook niet uit z'n duim, een directe Win32 allocatie is in VB sneller dan een malloc in C ;)

Verder ben ik het wel met je eens: voor het werken met audiobuffers kan je beter C gebruiken (of alles door DirectSound laten doen, die vervolgens exact dezelfde Win32 - of native API - calls gaat doen als jijzelf :P). Persoonlijk zou ik een DLL maken in C om de geluidsbuffers te beheren, en die gebruiken in een VB app waarin je de GUI implementeert. Best of both worlds :Y)

[ Voor 4% gewijzigd door johnwoo op 02-09-2003 15:45 ]

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
farlane schreef op 02 September 2003 @ 09:36:
[...]


Ligt het aan mij of ben ik de enige die hier een beetje bang van wordt ?

Als ik het goed begrijp gebruik je hier ongedocumenteerde functies uit de VB runtime om geheugen heen en weer te gooien ?
Klopt, het is maar net hoe graag je wilt blijven programmeren in VB.

Verwijderd

Geheugen verplaatsen kan ook gewoon met Win32 API (RtlMoveMemory).

Verwijderd

Topicstarter
_js_, (en anderen) bedankt voor de code. Ik ben ermee aan de slag gegaan maar heb nog niet echt bevredigende resultaten kunnen bereiken.

Ik zal nog kort uitleggen wat in essentie het probleem is:
Ik heb een pointer BufferIn.
Met een API call wordt er een wave file ingeladen. Na het laden wijst BufferIn naar de data van deze wave file. De data is een array van integers.

Dus: ik heb de POINTER van de wave data, namelijk BufferIn.
Echter, ik wil gewoon de DATA zelf kunnen bewerken.
De oplossing die ik nu heb is inderdaad de wave data kopieren naar een integer array zodat ik de beschikking heb over de wave data (sample(10) b.v.) maar dit is geen mooie oplossing aangezien je dan 2 keer de data in je geheugen hebt. Ik wil dus geen geheugen kopieren.

_js_, ik denk dat jouw functies niet de data kopieren maar ervoor zorgen dat ik de pointer van een zelf gedefinieerde array sample(0) kan wijzigen naar de pointer van BufferIn, klopt dit?

Ik heb hier geen VBA draaien op de universiteit, kan dus niet veel proberen...

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-08 18:33
johnwoo schreef op 02 September 2003 @ 15:43:
VB en de Win32 API gaan prima samen hoor, het gebruik van Win32 is niet voor niets zo eenvoudig in VB :)
Komt dat niet omdat VB wordt toegepast voor dingen waarvoor het niet bedoeld is ? ( De VB Taal/API schiet hiervoor gewoon tekort )
En over code vol API calls: wel eens een Win32 app in C gezien zonder API calls? :P
De taal C heeft voorzieningen om met pointers te werken, mag je kiezen voor unsigned datatypen en is in alle opzichten voor een andere toepassing bedoeld. VB is niet gemaakt om direkt API calls te doen. De Win32 API is gebouwd om vanuit C aan te roepen. ( Kijk alleen al naar het geouwehoer wat VB uithaalt met strings als je een dll call doet. Dat zijn toch lapmiddelen ? )
VB is veel schoner van calls dan C.
Dat kun je niet menen ..... VB is een bij elkaar geraapt zootje wat calls betreft.
Visual Basic .NET:
1
Open "blaat" For Output As #1


Dat ziet er toch niet uit ? Vergelijk het maar eens met een 'normale' functiecall in VB. De mogelijkheid om een dll functie te declareren is er ook pas later in gekomen.
Overigens zuigt malloc() het geheugen ook niet uit z'n duim, een directe Win32 allocatie is in VB sneller dan een malloc in C ;)
Ik zou het niet weten...heb je daar benchmarks van ? ( Overigens doe ik over snelheid geen uitspraken. Ik heb in VB nog nauwelijks problemen gehad daarmee )
Persoonlijk zou ik een DLL maken in C om de geluidsbuffers te beheren, en die gebruiken in een VB app waarin je de GUI implementeert. Best of both worlds :Y)
Idd, VB is sterk in het schermpjes gedeelte dus lijkt het mij logisch om het ook daar te gebruiken. Het rondgooien van geheugen en bitpielen gaat gewoon veel makkelijker in C ( Of een andere taal die hiervoor uitgerust is natuuurlijk )

[ Voor 6% gewijzigd door farlane op 02-09-2003 20:09 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

farlane schreef op 01 september 2003 @ 08:56:
Volgens mij zijn timers gebaseerd op de windows timers die een message posten naar je formulier window. Die draaien naar mijn weten niet in een andere thread.
idd, het zijn gewoon WM_TIMER messages die door de messagepump vanzelf bij de window aankomen. 1 thread dus. En zoals gezegd, de VB runtime is niet thread-safe, dus het zou niet eens kunnen
johnwoo schreef op 02 september 2003 @ 15:43:
[...]

VB en de Win32 API gaan prima samen hoor, het gebruik van Win32 is niet voor niets zo eenvoudig in VB :)
eenvoudig? Heb je de capriolen die je moet uithalen om die functies te definieren in VB dan ook meegerekend? In C is het simpelweg een #include <windows.h>, in VB moet je een heel tooltje opstarten om de juiste functiedefinities te vinden.
Overigens zuigt malloc() het geheugen ook niet uit z'n duim, een directe Win32 allocatie is in VB sneller dan een malloc in C ;)
Wat versta je onder een directe win32 allocatie? GlobalAlloc? Die is natuurlijk net zo goed in C te gebruiken. En het voordeel van C is dat je ook echt iets met dat geheugen kan, terwijl dat in VB nogal een probleem is.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 13:39

johnwoo

3S-GTE

farlane schreef op 02 September 2003 @ 20:06:
[...]


Komt dat niet omdat VB wordt toegepast voor dingen waarvoor het niet bedoeld is ? ( De VB Taal/API schiet hiervoor gewoon tekort )
Als het gebruik van een Win32 call een teken is dat een taal daar zelf niet voor bedoeld is, dan is C -onder Windows- ook nergens voor bedoeld :) Op het gebied van geheugenmanipulatie schiet VB inderdaad tekort, dat is zowel een sterkte als een zwakte van de taal (je kunt niks verneuken, maar je kunt het ook niet nuttig gebruiken).
De taal C heeft voorzieningen om met pointers te werken, mag je kiezen voor unsigned datatypen en is in alle opzichten voor een andere toepassing bedoeld. VB is niet gemaakt om direkt API calls te doen. De Win32 API is gebouwd om vanuit C aan te roepen. ( Kijk alleen al naar het geouwehoer wat VB uithaalt met strings als je een dll call doet. Dat zijn toch lapmiddelen ? )
VB is prima bedoeld om API calls te doen, net zoals C en iedere andere taal die __stdcall snapt. De string conversies zijn een poging om de RAD programmeur werk uit handen te nemen. In 99% van de gevallen is de conversie namelijk gewoon nodig, dus je kan beter in die ene uitzonderingsprocent moeilijk doen, dan in de overige gevallen zelf die conversie te moeten doen :)
Dat kun je niet menen ..... VB is een bij elkaar geraapt zootje wat calls betreft.
Visual Basic .NET:
1
Open "blaat" For Output As #1


Dat ziet er toch niet uit ? Vergelijk het maar eens met een 'normale' functiecall in VB. De mogelijkheid om een dll functie te declareren is er ook pas later in gekomen.
Ik bedoelde dat je in VB in een gemiddeld programma veel minder API calls nodig hebt dan in een gemiddeld C programma, omdat VB dat allemaal voor je doet. In C krijg je niet eens een venster op het scherm zonder zelf een call te doen. Verder ben ik het wel met je eens dat de C syntax veel systematischer is. Ik zie een Sub ook liever als een Function met return type void, maar wegens het vasthouden aan het verleden zit het nu eenmaal zo in elkaar. Over de eerste Basic versies (inmiddels ettelijke ingrijpende veranderingen ondergaan) is dus veel minder goed nagedacht dan over bijvoorbeeld C (relatief onveranderlijk).
Ik zou het niet weten...heb je daar benchmarks van ? ( Overigens doe ik over snelheid geen uitspraken. Ik heb in VB nog nauwelijks problemen gehad daarmee )
malloc() roept ook gewoon een Win32 API aan om z'n geheugen te vragen, zou best wel eens GlobalAlloc kunnen zijn. Een vriend van me gebruikt tegenwoordig geen libc meer in z'n Win32 C programma's, en vraagt het geheugen dus ook zelf bij Bill aan. Je programma wordt er lekker compact van :)
Idd, VB is sterk in het schermpjes gedeelte dus lijkt het mij logisch om het ook daar te gebruiken. Het rondgooien van geheugen en bitpielen gaat gewoon veel makkelijker in C ( Of een andere taal die hiervoor uitgerust is natuuurlijk )
Helemaal mee eens :)

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

johnwoo schreef op 02 September 2003 @ 22:10:
malloc() roept ook gewoon een Win32 API aan om z'n geheugen te vragen, zou best wel eens GlobalAlloc kunnen zijn. Een vriend van me gebruikt tegenwoordig geen libc meer in z'n Win32 C programma's, en vraagt het geheugen dus ook zelf bij Bill aan. Je programma wordt er lekker compact van :)
niet 'gewoon'. malloc () alloceert grote blokken met VirtualAlloc, wat vervolgens weer onderverdeeld wordt in de blokken die jij alloceert met malloc (). Als je 2 blokken, die fysiek achter elkaar zitten, vrijgeeft, dan kun je daar weer een groter blok alloceren. Dit zijn dingen die de C runtime zelf doet, niet de win API

Overigens staat er bij GlobalAlloc in de MSDN:
Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE, the clipboard functions, and OLE data objects.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
Verwijderd schreef op 02 september 2003 @ 19:55:
_js_, ik denk dat jouw functies niet de data kopieren maar ervoor zorgen dat ik de pointer van een zelf gedefinieerde array sample(0) kan wijzigen naar de pointer van BufferIn, klopt dit?

Ik heb hier geen VBA draaien op de universiteit, kan dus niet veel proberen...
Dat klopt, om een array van integers te gebruiken moet je de originele array declareren als

Dim temp(0) As Integer

en nadat je de eerste putmem4s (met BufferIn i.p.v. strptr(...)) hebt gedaan kun je je data benaderen met temp(x) waar x de zoveelste integer is in je data, beginnend met 0.

En je hebt vast wel VBA, dat zit in MS Word, Access, etc.

(trouwens, ik heb een kleine fout uit de eerder geposte code gehaald, misschien controleren of je die fout hebt overgenomen)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-08 18:33
johnwoo schreef op 02 September 2003 @ 22:10:
[...]

Als het gebruik van een Win32 call een teken is dat een taal daar zelf niet voor bedoeld is, dan is C -onder Windows- ook nergens voor bedoeld :)
[...]
VB is prima bedoeld om API calls te doen, net zoals C en iedere andere taal die __stdcall snapt. De string conversies zijn een poging om de RAD programmeur werk uit handen te nemen.
[...]
Ik bedoelde dat je in VB in een gemiddeld programma veel minder API calls nodig hebt dan in een gemiddeld C programma, omdat VB dat allemaal voor je doet.
Misschien is het een kwestie van smaak, maar ik vind ( .... ) dat VB gemaakt is om snel en makkelijk iets in elkaar te draaien. De hele taal is zo gemaakt dat het 'de RAD programmeur werk uit handen neemt'

De taal VB en de VB API zitten dan ook zo in elkaar dat je over geheugenbeheer niet druk hoeft te maken, niet hoeft te weten dat er een messagepump bestaat, en dat een timer op een formulier hoort te staan etc.

Door deze opbouw komt VB als taal gewoon dingen te kort om op alle gebieden te kunnen worden toegepast.
Als ( half ) antwoord daarop hebben ze mogelijkheden ingebouwd om API calls te kunnen doen, ware het niet dat dit wat andere problemen met zich meebracht. ( Hmm, deze API verwacht een functiepointer, en nu ? Hey, we maken een nieuw keyword die AddressOf heet !)
En zo ben je dus toch weer met pointers bezig.

Naar mijn idee schiet dit voorbij aan de doelstelling van Basic.

Maargoed, ik geloof dat men in VB.NET overnieuw begonnen is dus misschien wordt het beter. :)

Nogmaals, Basic heeft zijn toepassingen waar ik het uitermate geschikt voor vind. ( Maar die toepassingen hoeven geen GlobalAlloc, CopyMemory of callbacks te gebruiken ;) )

[ Voor 3% gewijzigd door farlane op 03-09-2003 09:29 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
OK ik snap eindelijk hoe het werkt. Uiteindelijk ben je dus gewoon wijzigingen aan het doorvoeren in de SAFEARRAY structure van VB. Na de 12e byte staat een long met een pointer naar de data zelf. Na de 16e byte staat hoeveel elementen de array heeft, of eigenlijk de 'bound' van de data.

Stukje testcode, geklust in VBA in Word :):

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
'een source maken
    Dim size As Long
    size = 5
    Dim source() As Integer
    ReDim source(0 To size - 1) As Integer

'source vullen
    Dim i As Integer
    For i = 0 To size - 1
        source(i) = i
        Debug.Print "source #" & i & "    = " & source(i)
    Next i

'pointer naar source DATA
    Dim SourceDataPtr As Long 'pointer naar de DATA in de SAFEARRAY die source heet
    SourceDataPtr = VarPtr(source(0)) 'dit is pointer naar eerste element in de DATA
    
'nieuwe safearray definieren, sample data
    Dim sample(0) As Integer
    Dim arrayinfo As arrayinfo
    GetMem4 VarPtrArray(sample()), arrayinfo.infoptr 'pointer naar de SAFEARRAY
    PutMem4 arrayinfo.infoptr + 12, SourceDataPtr 'de long na de 12e byte bevat de pointer naar de data
    PutMem4 arrayinfo.infoptr + 16, size 'de long na de 16e byte bevat de bound, oftewel de grootte van de array

    For i = 0 To size - 1
        Debug.Print "sample #" & i & "    = " & sample(i)
    Next i


Dit werkt prima. Hoewel, als ik de code direct NOG een keer run dan loopt het zaakje vast. Ik denk dat ik eerst weer het geheugen moet opruimen? Hoe zou dat gedaan kunnen worden?

In feite loop je dus gewoon in de SAFEARRAY dingen te doen. Daarom zou het volgende ook moeten werken, zonder gebuik te maken van de arrayinfo:
Visual Basic:
1
2
3
4
5
    ...
    Dim sample(0) As Integer
    PutMem4 VarPtrArray(sample()) + 12, SourceDataPtr
    PutMem4 VarPtrArray(sample()) + 16, size
    ....


Echter dit werkt niet, ik snap nu niet waarom niet.
!!EDIT: ik heb het door, gewoon goed lezen. Het adres VarPtrArray(sample()) is niet het begin van de SAFEARRAY, maar daarin staat het adres van de safearray (of safearray info). Dus DAT adres uitlezen met getmem, en dan hieraan relateren met +12 en +16 etc.

Natuurlijk vragen jullie je af waarom gaat die gast niet gewoon lekker in C++ verder, maar ik MOET dit nu gewoon weten :) en ik vind het ook een vrij leerzame les aan het worden. Heb nog wat lopen zoeken op tha web over getmem en putmem, is een interessant artikel:
http://www.xbeat.net/vbspeed/i_VBVM6Lib.html

[ Voor 9% gewijzigd door Verwijderd op 03-09-2003 15:49 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-08 18:33
Verwijderd schreef op 03 September 2003 @ 15:41:

[....................................]
Natuurlijk vragen jullie je af waarom gaat die gast niet gewoon lekker in C++ verder,...
Ja inderdaad :)
maar ik MOET dit nu gewoon weten :) en ik vind het ook een vrij leerzame les aan het worden.
En dat kan ik me ook goed voorstellen. :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
Ik denk dat het vast loopt omdat je de array naar je eigen data laat verwijzen. Wanneer VB ziet dat het einde Function is gaat VB proberen het gebruikte geheugen weer vrij te geven, en dat levert problemen op wanneer je data al weg is of je geluidsroutines de data later nog eens benaderen. Of misschien kan het vrijgeven al niet.

Om te zorgen dat alles netjes verloopt moet je nadat je klaar bent met je eigen data de array weer naar de originele inhoud van de array verwijzen. Wanneer VB de boel opruimt gaat het allemaal netjes. Je eigen data moet je zelf opruimen, er zal wel een api call zijn die de buffer weer vrijgeeft, staat waarschijnlijk wel aangegeven in dezelfde handleiding waar in staat hoe je je data in de eerste plaats declareert/instantieert. (Zie ook het stuk code dat ik gepost heb, en let op de comments die iets zeggen over "misschien belangrijk voor cleanup")
Pagina: 1