[C++] Syntax Vraag

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

  • Cassius
  • Registratie: Januari 2002
  • Niet online
Beste medetweakers :) ,

Ik ben al lang bezig met een projectje en heb het er nogal moeilijk mee, progressie boek ik als een slak, maar stukje bij beetje :) . Ik ben ook een beginner op dit gebied.

Om meteen met de deur in huis te vallen:

SI_GetNumDevices() Returns the number of devices connected

Oke prima die heb ik nodig, dan kijk ik bij de uitleg:

SI_STATUS SI_GetNumDevices (LPDWORD NumDevices)

Parameteres --> "NumDevices: Address of a DWORD variable that will contain the number of devices connected on return"
Return value --> "SI_STATUS = SI_SUCCESS or SI_DEVICE_NOT_FOUND or SI_INVALID_PARAMETER"

Ik vraag me dan af hoe ik die functie aanroep. Als ik gewoon code SI_GetNumDevices(); klop, en vervolgens code ik cout << "NumDevices" << endl; dan geeft hij niets terug de belhamel.

(tussendoor http://blogs.msdn.com/old...ve/2005/12/28/508689.aspx gelezen)

Ik begrijp nog steeds niet wat een LPDWORD precies is, wel dat hij hem moet hebben in de aanroep. Maar ook niet hoe ik het getal van aangesloten devices kan laten zien. Grmbl.

Nog zo'n functie is:

SI_OPEN()

SI_STATUS SI_OPEN (DWORD DeviceNum, HANDLE *Handle, LPVOID Buffer, BYTE Test)

Hij wil graag een DWORD, een pointer (?) en nog meer dingen. Ik raak gewoon aan het tollen. Ben simultaan bezig in het boek " http://books.google.nl/bo...3D&sa=X&oi=print&ct=title " maar ik loop er gewoon tegen op. Ik ben niet echt bang voor programmeren, maar verlies de lol doordat je als beginner soms tegen dit soort dingen hard oploopt terwijl het (volgens mij) enorm basic is.

Mocht er iemand goed zijn in uitleggen en me een schop in de juiste richting willen geven, heel graag!

De meeste mensen deugen!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Cassius schreef op vrijdag 06 juli 2007 @ 15:25:
Ik vraag me dan af hoe ik die functie aanroep. Als ik gewoon code SI_GetNumDevices(); klop, en vervolgens code ik cout << "NumDevices" << endl; dan geeft hij niets terug de belhamel.
Geef eens de exacte code (in een code tag). Want dit zou gewoon letterlijk "NumDevices" moeten outputten - je geeft het immers gewoon een string.
Ik begrijp nog steeds niet wat een LPDWORD precies is
Een pointer naar een DWORD
Nog zo'n functie is:

SI_OPEN()

SI_STATUS SI_OPEN (DWORD DeviceNum, HANDLE *Handle, LPVOID Buffer, BYTE Test)

Hij wil graag een DWORD, een pointer (?) en nog meer dingen.
Die pointer is waarschijnlijk om de HANDLE in op te vangen. De functie geeft namelijk al een status terug, dus hij kan daarnaast niet ook nog een HANDLE teruggeven, waarin je geinteresseerd bent. Je geeft dus een pointer mee naar een HANDLE variabele waar de functie het resultaat in op mag slaan.

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.


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07 12:07
Nog ter verduidelijking

HANDLE tLegeHandle = NULL; //aan te nemen dat HANDLE = void*
SI_STATUS status = SI_OPEN(1, &tLegeHandle, aBuffer, 1);

tLegeHandle != NULL....

als beginneling met LPVOID en dergelijke bezig zijn is normaal: pointer 'snap' je of niet. Misschien aan te raden eerst in Java / C# te beginnen om dat 'af te zakken' naar C / C++

[ Voor 4% gewijzigd door hobbit_be op 06-07-2007 19:35 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 27-11 20:42
Hungarian coding is nou niet het meest makkelijk om te begrijpen voor beginners (zelfs ik volg de logica erachter niet helemaal, het is gewoon een absurd systeem!). De LP-prefix geeft in ieder geval altijd aan dat het een pointer betreft en 'DWORD' is (in de meeste gevallen!) een int (32-bits). De functie SI_GetNumDevices(LPDWORD numDevices) verwacht dus als parameter het adres van (=pointer naar) een int waarin die functie het aantal devices kan terugzetten. SI_STATUS is dan een of ander type dat een waarde bevat over of de operatie geslaagd is of niet. De volgende code hoort dus te werken:

C++:
1
2
3
4
DWORD numDevices = -1;
SI_GetNumDevices(&numDevices);

cout << numDevices << endl;


Het heeft mij, toen ik met C++ begon, ook even geduurd voordat ik zelfs maar de simpele calls als GetUserName(LPTSTR name); snapte. Echter, als je dat eenmaal doorhebt (en zoals gezegd: de win32-API is niet de meest makkelijke om mee te beginnen!) ben je eigenlijk in staat om alle functies uit de win32-API in ieder geval te snappen en te gebruiken :) Even doorzetten dus! Misschien moet je eerst eens beginnen met wat makkelijks (maak eens een programma 'whoami' die alleen maar de huidige gebruikersnaam en eventueel computernaam uitspuugt; of, als je iets verder bent, een programma dat recursief door mappen gaat zoeken naar een bestand, ofzo).

[ Voor 11% gewijzigd door MisterData op 06-07-2007 19:48 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

MisterData schreef op vrijdag 06 juli 2007 @ 19:45:
Hungarian coding is nou niet het meest makkelijk om te begrijpen voor beginners (zelfs ik volg de logica erachter niet helemaal, het is gewoon een absurd systeem!)
Ten eerste heeft dit niets met hungarian notation te maken (die formatteert namelijk variabele-namen, niet types zelf), en ten tweede is de hungarian notation zoals uitgevonden door de originele hongaar Charles Simonyi absoluut niet absurd maar juist heel logisch. Het gaf het gebruik van een variabele aan (en dus niet het type). Een int of float als grootte voor iets geef je bijvoorbeeld een s prefix (van size), terwijl een hoeveelheid juist een n krijgt (number). Daardoor is het in de code duidelijk waar het voor dient. Dit is helaas niet helemaal zoals door hem bedoeld overgenomen en kreeg het uiteindelijk de prefix van het type, wat natuurlijk ontzettend nutteloos is aangezien je dat ook wel aan de code af kunt lezen (zeker met de IDEs van vandaag de dag).

De LP in de win32 API staat trouwens voor Long Pointer. Hou er rekening mee dat veel van de originele API functies nog uit de win16 tijd stammen, waar pointers zowel 16 als 32 bits konden zijn, vandaar dus de long. DWORD komt natuurlijk van double-word - een word is in de x86 wereld gedefinieerd als 16 bits, een doubleword is dus 32 bits. Verder heb je nog heel veel string varianten, zoals LPSTR, LPTSTR, LPWSTR, etc. De STR staat natuurlijk voor string, en de LP is al bekend, maar de W wordt gebruikt voor unicode strings (wchar_t*), de T is char of wchar_t, afhankelijk van je unicode setting waarmee je compilet. Vaak staat er ook nog een C tussen, wat aangeeft dat het een const string 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.


Verwijderd

Just curious, maar waar staat LPVOID dan voor? Een pointer naar 'niks' of naar 'iets dat er niet toe doet' of zo? En wat is 't nut ervan?

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Verwijderd schreef op zaterdag 07 juli 2007 @ 01:32:
Just curious, maar waar staat LPVOID dan voor? Een pointer naar 'niks' of naar 'iets dat er niet toe doet' of zo? En wat is 't nut ervan?
Een void * idd. Da's in essentie een typeloze pointer. Null is ook meestal gedefinieerd als void *null = 0; 't handige daaraan is dat je bij een functie foo(int *blah) gewoon null in kunt vullen zonder dat je compiler gaat mekkeren dat je een verkeerd soort pointer doorstuurt. En als je bijvoorbeeld een callback functie hebt kun je void pointers ook gebruiken om bijvoorbeeld een eigen stuk data mee te sturen waarbij je dan niet afhankelijk bent van wat voor soort data dat is. Zolang jij 't maar weet en terugcast naar wat 't is. Bijvoorbeeld een functie setCallback(char *deredenvoordecallback, int (*callbackFunctie)(), void *data); kun je in die data een struct met info zetten. De callback kan dan aangeroepen worden als bijvoorbeeld callbackFunctie(data); zonder dat de implementatie zich zorgen hoeft te maken over wat er in dat data veld staat.

[ Voor 35% gewijzigd door CyBeR op 07-07-2007 01:41 ]

All my posts are provided as-is. They come with NO WARRANTY at all.


  • remco_k
  • Registratie: April 2002
  • Laatst online: 21:24

remco_k

een cassettebandje was genoeg

CyBeR schreef op zaterdag 07 juli 2007 @ 01:38:
[...]
Een void * idd. Da's in essentie een typeloze pointer. Null is ook meestal gedefinieerd als void *null = 0; 't handige daaraan is dat je bij een functie foo(int *blah) gewoon null in kunt vullen zonder dat je compiler gaat mekkeren dat je een verkeerd soort pointer doorstuurt. En als je bijvoorbeeld een callback functie hebt kun je void pointers ook gebruiken om bijvoorbeeld een eigen stuk data mee te sturen waarbij je dan niet afhankelijk bent van wat voor soort data dat is. Zolang jij 't maar weet en terugcast naar wat 't is. Bijvoorbeeld een functie setCallback(char *deredenvoordecallback, int (*callbackFunctie)(), void *data); kun je in die data een struct met info zetten. De callback kan dan aangeroepen worden als bijvoorbeeld callbackFunctie(data); zonder dat de implementatie zich zorgen hoeft te maken over wat er in dat data veld staat.
Ik noem het altijd een blinde pointer.
... wat natuurlijk voor luie programmeurs is en vooral een erg gevaarlijke manier van gebruik van pointers. Je kan hier gemakkelijk de meest waardelozee fouten maken en daarmee de meest wazige uitvoeringen krijgen. (stuur maar eens een bool mee en lees een int terug... )
Zolang je als programmeur je eigen 'dingen' maakt; gebruik dan nooit de void * pointer.
Die keren dat ik 'm gebruikte, is niet uit noodzaak maar luiheid. Definieer gewoon een goed type/class/struct.
Soms kan je er niet omheen. Als ik een listview gebruik hang ik graag wat data in de vorm van een struct aan het TListItem::Data (die void* is). Maar daar heb ik verder weinig keus...

Voor wat betreft de windows API, idd daar had ik in den beginne ook erg veel moeite mee.
Ik kende voor die tijd ook alleen maar functies die waarden terug gaven, maar niet via 1 van hun parameters. Maar zoals gezegd, zo moeilijk is het echt niet (ik durf nu te stellen dat het gewoon makkelijk is -> kinderspel) en dit 'systeem' word bij meerdere API's gebruikt.

[ Voor 4% gewijzigd door remco_k op 07-07-2007 09:02 ]

Alles kan stuk.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

remco_k schreef op zaterdag 07 juli 2007 @ 09:00:
Zolang je als programmeur je eigen 'dingen' maakt; gebruik dan nooit de void * pointer.
Zolang je als programmeur je eigen 'dingen' maakt, gebruik dan sowieso geen native pointers. Da's alleen maar vragen om problemen.

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.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Als je bijvoorbeeld Visual Studio gebruikt kun je er heel snel echter komen wat voor een ding iets precies is. Je tikt het in, RMB, Go to definition.

Uiteindelijk blijken het allemaal macro's te zijn :)

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.


  • remco_k
  • Registratie: April 2002
  • Laatst online: 21:24

remco_k

een cassettebandje was genoeg

.oisyn schreef op zaterdag 07 juli 2007 @ 13:44:
[...]

Zolang je als programmeur je eigen 'dingen' maakt, gebruik dan sowieso geen native pointers. Da's alleen maar vragen om problemen.
Waarom?
Omdat je bang bent voor een memory leak?

Alles kan stuk.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
remco_k schreef op maandag 09 juli 2007 @ 09:57:
[...]

Waarom?
Omdat je bang bent voor een memory leak?
Idd, je kan dan beter gebruik maken van iets als een auto_ptr

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Om dit soort problemen te voorkomen dus. Als je idd gebruik maakt van auto_ptr, of andere smartpointers zoals boost::shared_ptr en boost::weak_ptr, dan weet je zeker dat de data waarna ze wijzen altijd valid óf null is, en dat je geheugen vrijgeeft op het moment dat zo'n object buiten scope gaat.

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.


  • remco_k
  • Registratie: April 2002
  • Laatst online: 21:24

remco_k

een cassettebandje was genoeg

.oisyn schreef op maandag 09 juli 2007 @ 14:34:
Om dit soort problemen te voorkomen dus. Als je idd gebruik maakt van auto_ptr, of andere smartpointers zoals boost::shared_ptr en boost::weak_ptr, dan weet je zeker dat de data waarna ze wijzen altijd valid óf null is, en dat je geheugen vrijgeeft op het moment dat zo'n object buiten scope gaat.
Daar heb je gelijk in. Als je als programmeur je eigen pointers beheerd, dan kan je dat ook fout doen en dan kunnen er inderdaad de meest wazige dingen gebeuren op plekken die *niets* met het oorspronkelijke probleem te maken hebben. Maar then again; wel slordig van die programmeur.
auto_ptr zijn gewoon makkelijk in het gebruik en kan verder weinig mee misgaan op dat gebied.

Maar om even een einde te maken aan deze topic hijack, hoe is het nu met de topicstarter afgelopen? Cassius ? Heb je het door of lig je huilend over je buro? :+

Alles kan stuk.

Pagina: 1