Toon posts:

[C++] sprintf later gebruiken

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb het volgende probleem.

#include "stdio.h"
#include "stdarg.h"

void PutToBuffer(int first,...);

char buffer[200]={0};

void main()
{
char ch[200];
int i=1234,k,l;

//printf(ch);

PutToBuffer(i,i,(i==12346)?"ON":"OFF");

}

void PutToBuffer(int first,...)
{
va_list marker;
va_start(marker,first);
}

De functie PutToBuffer moet nu de variabele argumenten in een string zetten, zonder gebruik te meken van sprintf en een formatstring.

Heeft iemand enig idee hoe je toch het einde van de variabele argumenten m.b.v. de va_listpointer kunt achterhalen?

Ik wil dit graag, omdat ik dit op een embedded systeem wil laten draaien, die alleen codes i.p.v. strings naar buiten spuugt, waarna de pc aan de hand van de codes de formatstring opzoekt en de variabelen weer te voorschijn tovert. Strings en sprintf nemen te veel geheugenruimte in. Het gaat hier om veel strings, ook met variabele lengte.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-09 00:49
Weet je zeker dat je topic [C++] sprintf klopt? Meestal wordt op embedded systemen waar memory echt beperkt is C ipv C++ gebruikt.

Zo ja, dan is de oplossing om de varargs te dumpen en iostream style overloading te gebruiken. De compiler kan dan effectiever bepalen welke code nodig is.

Zo nee, dan moet je in een fixed argument de informatie
meegeven waaruit de vararg functie kan bepalen hoeveel
argumenten er van welk type zijn. De va_list zelf kun je daar niet voor gebruiken

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
Het is inderdaad in C.
Ik wil juist niet meegeven wat voor types er gebruikt worden.
Is er geen enkele andere manier om te zien waar de variabele argumentenlijst stopt?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

alleen als je m laat eindigen met een bepaalde waarde (bijvoorbeeld NULL, maar dan kun je weer geen 0 gebruiken als integer).

Bovendien is er geen manier om te controleren wat voor type het 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.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op donderdag 11 april 2002 12:59 schreef .oisyn het volgende:
alleen als je m laat eindigen met een bepaalde waarde (bijvoorbeeld NULL, maar dan kun je weer geen 0 gebruiken als integer).

Bovendien is er geen manier om te controleren wat voor type het is
Je kunt theoretisch al je parameters als een variant meegeven, ben je alleen wel gebonden aan je eigen protocol en knalt het als de tyfus als je dat niet doet. Scheelt wel overigens dat je dan als list-terminator een empty-variant kunt geven.

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-09 00:49
Op donderdag 11 april 2002 12:59 schreef .oisyn het volgende:
alleen als je m laat eindigen met een bepaalde waarde (bijvoorbeeld NULL, maar dan kun je weer geen 0 gebruiken als integer).

Bovendien is er geen manier om te controleren wat voor type het is
Nee - werkt niet; je moet het type (goed) voorspellen. En als je het fout doet mag je proggie crashen. Dus als je een pointer past, en daarna checkt of er een 0(int) argument gepassed was, dan gaat't fout.
Het vervelende is dat compilers juis op dit soort punten verschillen, zeker tussen een Win/Unix desktop enerzijds en embedded systeem anderzijds. Embedded systemen hebben gekkere pointers en calling conventions dan desktops. Dus je proggie kan het op je PC rustig doen en vervolgens hard crashen als je geen debugger meer hebt.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-09 00:49
Op donderdag 11 april 2002 13:54 schreef curry684 het volgende:

[..]

Je kunt theoretisch al je parameters als een variant meegeven, ben je alleen wel gebonden aan je eigen protocol en knalt het als de tyfus als je dat niet doet. Scheelt wel overigens dat je dan als list-terminator een empty-variant kunt geven.
Ik dacht dat alleen built-in types via een vararg list meegegeven konden worden, dus niet een variant type. Zie bv. printf wat alleen built-in types kan printen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op donderdag 11 april 2002 15:47 schreef MSalters het volgende:
Ik dacht dat alleen built-in types via een vararg list meegegeven konden worden, dus niet een variant type. Zie bv. printf wat alleen built-in types kan printen.
Hint:
code:
1
2
3
4
MyVariant   l_Variant(15, e_VtInteger);
void*    l_VoidPointer = &l_Variant;

printf("%d", l_VoidPointer);

:7

Professionele website nodig?


Verwijderd

Topicstarter
Ik moet in ieder geval weten wat het type is.
Er treden in mijn geval 2 modelijkheden op. Of het zijn vaste getallen die als 4 bytes verstuurt kunnen worden. Of het zijn strings met 0-terminator.
Voor de strings moet ik dus weten of het argument een pointer is of niet.

int k;
Nu zet de compiler de naam plus het adres in een tabel en reserveert het genoeg geheugen voor een int.

int *k;
Nu zet de compiler de naam en het adres waar de pointer in staat in de tabel. Maar wat doet hij met het type.
Want als ik hierna k=new k[10]; doe (at run time), dan weet de "processor" dat hij 10 ints moet reserveren.

Is het op deze manier niet ergens te vinden of een argument een pointer is en van welk type?

Verwijderd

Op donderdag 11 april 2002 17:06 schreef jw.oosting het volgende:
Is het op deze manier niet ergens te vinden of een argument een pointer is en van welk type?
Nee, het is gewoon geheugen, meer niet. Als je types etc. wilt dan moet je echt een overhauling iets gebruiken, maargoed, als we het dan toch over overhead hebben ;)

Gewoon de sprintf manier gebruiken. Als dat makkelijker kon dan was dat echt wel makkelijker :)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op donderdag 11 april 2002 17:06 schreef jw.oosting het volgende:
Is het op deze manier niet ergens te vinden of een argument een pointer is en van welk type?
Het is allebei gewoon 32-bits data dus dat is niet meer te herkennen. Tenzij je een custom variant maakt die het type erbij geeft.

WEL een mogelijkheid is overigens iets waar Windows ook gebruik van maakt, en dat is als je geen 32-bit maar 16-bit integers nodig hebt: je kunt dan de bovenste 16-bits op 0 laten wat (volgens Win32 API in ieder geval) een valide manier is om te checken of het een pointer is. Zo niet heb je een short in de onderste 16 bits.

Laatste optie is om 64-bits integers op dezelfde manier te gebruiken maar dat kun je op een embedded systeem denk ik vergeten :)

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09-09 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wat je natuurlijk ook kunt doen is wel gewoon 32 bits gebruiken, en de bovenste bit aanzetten als het een string voorstelt. Nadeel hiervan is wel dat je maar 31 bits voor een integer kan gebruiken (en niet 4 gig addressspace, maar ik denk niet dat dat embedded systeem dat heeft :))

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.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op vrijdag 12 april 2002 14:05 schreef .oisyn het volgende:
(en niet 4 gig addressspace, maar ik denk niet dat dat embedded systeem dat heeft :))
Je kunt nooit garanderen dat de mem-controller van dat ding z'n 4Kb RAM niet ergens op 0xFFFF0000 mapt... :)

Sowieso is het lullig dat je dan niet meer veilig onder Windows kunt testen voordat je het in een chip fikt (op te lossen met defines overigens zodat je onder Windows zelf __int64 integers gebruikt).

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-09 00:49
Op vrijdag 12 april 2002 11:08 schreef curry684 het volgende:

[..]

Het is allebei gewoon 32-bits data dus dat is niet meer te herkennen. Tenzij je een custom variant maakt die het type erbij geeft.

WEL een mogelijkheid is overigens iets waar Windows ook gebruik van maakt, en dat is als je geen 32-bit maar 16-bit integers nodig hebt: je kunt dan de bovenste 16-bits op 0 laten wat (volgens Win32 API in ieder geval) een valide manier is om te checken of het een pointer is. Zo niet heb je een short in de onderste 16 bits.

Laatste optie is om 64-bits integers op dezelfde manier te gebruiken maar dat kun je op een embedded systeem denk ik vergeten :)
32 bits kun je vaak ook vergeten. Zelfs al heeft het embedded systeem 32 bits pointers en integers; de 16 van 32 bits 0-conventie die je noemt is specifiek voor Windows. Zelfs UNIX heeft dat niet.

Wat eventueel ook kan werken is zorgen dat al je integers in een bekend stuk geheugen staan, en altijd een void* pointer passen. In het geval dat je een integer bedoelt, dan pass je de int* daar naar toe.

Maar het blijft het geval dat de varargs niet handig zijn. Gebruik gewoon chained operators, a la operator<< voor std::ostream maar dan voor je eigen buffer.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1