using void * ?

Hi, I've got a problem using void *

I'm using sqlite in this way:
1
2
3
4
5
6
7
unsigned int *anzahl=NULL;
	...
	anzahl=(unsigned int*)malloc(sizeof(int));
	rc=sqlite3_exec(this->Database, (sql.str()).c_str(), calllback_getanz, &anzahl, &zErrMsg);
...
if (*anzahl<ANZTEILNEHMER)
...


and my callback function is like this:
1
2
3
4
5
6
int	calllback_getanz(void *p_Daten, int argc, char **argv, char **SpaltenNamen)
{
cout << "Callback " << argv[0]<< endl;
	p_Daten=&argv[0];
	return 0;
}


Output is : Callback 0. 0 is ok. But when I try to get the value in my if part its something like 3077620096.

How do I use the void * correctly?
This is waaaaaay out there, but is it because there are THREE l's in line 1, second example?
It's just the name. And it's written with 3l's in the sqlite3_exec so that's no problem. I correct it but it's the same :(

Callback 0
and in the if -> anzahl = 3077620096 or something like that
Last edited on
I can't help you. I just started myself. D:
On the other hand, maybe people like Grey Wolf will see this topic and answer this.

Edit: Wow. A programmer not afraid to admit mediocrity.
I rule.
Last edited on
The p_Daten is the address of the number pointer (which you have set to NULL).

So inside your callback you can do something to the number (anzahl), like allocate memory or something.

p_Daten is a local (read: temporary) variable, so you can assign anything you want to it, but once the callback returns whatever you did is lost.

The same is true for argv[n]. Everything in argv[] is a temporary variable, so if you remember the address of any one of them it is meaningless once the callback returns.

Finally, it looks like you are mixing data types. anzahl is a pointer to int, but the returned record is a pointer to char. You need to convert from char* to int.

This will remember the number from the last record returned:
1
2
3
4
char zErrMsg[ MAX_STRING ];
unsigned int anzahl;
int rc = sqlite3_exec( this->Database, sql.str().c_str(), calllback_getanz, &anzahl, &zErrMsg );
if (anzahl < ANZTEILNEHMER) ...

1
2
3
4
5
6
int calllback_getanz( void *p_Daten, int argc, char **argv, char **SpaltenNamen )
  {
  if (argc < 1) return 0;
  *(unsigned int*)p_Daten = strtoul( argv[ 0 ], NULL, 0 );
  return 0;
  }

All it does is translate the string version of the number in argv[ 0 ] (if any) to an actual number and store it in anzahl for every record returned. Since each record's number overwrites the last number placed in anzahl only the last record's number is available after the call to sqlite3_exec().

BTW. You don't need to name your callback calllback_anything(). You can name it whatever you like.

Hope this helps.
Last edited on
Thanks, that works.
And thanks for the detailed explanation. I think, I understand :)
It's me again.

Does this work for stl, too?
i've had:
((vector<string>)p_Daten).push_back((string)(argv[0]));

but it says:
error: invalid conversion from void* to unsigned int

Why unsigned int?

complete function:
1
2
3
4
5
6
int callback_getuser(void *p_Daten, int argc, char **argv, char **SpaltenNamen)
{
	if (argc < 1) return 0;
	((vector<string>)p_Daten).push_back((string)(argv[0]));
	return 0;
}



call:
1
2
vector<string> gruppen;
rc=sqlite3_exec(this->Database, (sql.str()).c_str() ,callback_getuser, &gruppen, &err);

I don't know about that unsigned int, but line 4 should read something like

(vector<string>*)(p_Daten)->push_back( string( argv[ 0 ] ) );

Remember, p_Daten is a pointer to a vector, not a vector.

Using the vector was a great idea!
pointer... that's it

thanks again
Topic archived. No new replies allowed.