Returning values as Void *

M

Mark Antony

Hello everyone,

I am writing a function that takes a void* as an argument. In this
function, there is some data that needs to be given back in the form
of a void pointer. This is the simple test that I am trying to do:

////////////////////////CODE/////////////////////////////////

#include <stdio.h>

long f(int i, void *b){
float*fp;
char* a = "Hello";
float*tp = (float *)a;

printf("tp = %p\tb = %p\n", tp, b);
b = tp;
printf("tp = %p\tb = %p\n", tp, b);

return 0;
}


int main() {
void* pb;

printf("pb = %p\n", pb);
f(2, pb);
printf("pb = %p\n", pb);

return 0;
}


///////////////////////////END CODE///////////////////////
///////////////////////////OUTPUT//////////////////////////
pb = CCCCCCCC
tp = 00422030 b = CCCCCCCC
tp = 00422030 b = 00422030
pb = CCCCCCCC
///////////////////////////END OUTPUT//////////////////////

But what I want is that inside the function that I call, the void
pointer should be redirected, i.e. pb should be equal to 00422030, pb
= b.

(I know the above code is weird but I want to illustrate the fact that
I am trying to make the void* point to another place).

I think that this should be possible and the void pointer should point
to the address that I want to in the function.

But this is not happenning. Please help.

Thanks for everyone who replies.

With best regards,
Mark Antony
 
T

Todd Winks

Mark Antony said:
Hello everyone,

I am writing a function that takes a void* as an argument. In this
function, there is some data that needs to be given back in the form
of a void pointer. This is the simple test that I am trying to do:

////////////////////////CODE/////////////////////////////////

#include <stdio.h>

long f(int i, void *b){
float*fp;
char* a = "Hello";
float*tp = (float *)a;

printf("tp = %p\tb = %p\n", tp, b);
b = tp;
printf("tp = %p\tb = %p\n", tp, b);

return 0;
}


int main() {
void* pb;

printf("pb = %p\n", pb);
f(2, pb);
printf("pb = %p\n", pb);

return 0;
}


///////////////////////////END CODE///////////////////////
///////////////////////////OUTPUT//////////////////////////
pb = CCCCCCCC
tp = 00422030 b = CCCCCCCC
tp = 00422030 b = 00422030
pb = CCCCCCCC
///////////////////////////END OUTPUT//////////////////////

But what I want is that inside the function that I call, the void
pointer should be redirected, i.e. pb should be equal to 00422030, pb
= b.

(I know the above code is weird but I want to illustrate the fact that
I am trying to make the void* point to another place).

Function f() is only altering the value of its local copy of the pb
variable, not the value of the variable itself, which is what you're after.
Parameters that are to have their values changed by a function should be
passed "by reference" - i.e. pass the address of the parameter, not its
value, and should then be dereferenced inside the function.

To do that, change the "void *b" in the declaration of f() to "void **b",
and change each use of the variable b in f()'s definition to *b, e.g. change
"b = tp" to "*b = tp".

Then each call to f() needs to pass the address of the pointer to be
changed, e.g. in main() change "f(2, pb)" to "f(2, &pb)".

Cheers,
Todd
 
J

Jeff

Mark Antony said:
Hello everyone,

I am writing a function that takes a void* as an argument. In this
function, there is some data that needs to be given back in the form
of a void pointer. This is the simple test that I am trying to do:

////////////////////////CODE/////////////////////////////////

#include <stdio.h>

long f(int i, void *b){
float*fp;

Why don't use long* here ?
char* a = "Hello";
float*tp = (float *)a;

printf("tp = %p\tb = %p\n", tp, b);
b = tp;

Here b is the value contained in pointer "void* b". If you want to change the pointer "void* b"
itself, you have to use "pointer of pointer".

void **b
 
M

Mark Antony

Thanks to Jeff and Todd for their reply.

What you told me is correct. But I want to do something like this:

//////////////////////////////////////CODE///////////////////////////

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

long f(int a, void* b) {
float* c;
char* df1;
long q = 123456;
long* df2 = &q;

*b = q;

return 0;
}

int main() {
long w;

f(2, &w);
printf("w = %u\n", w);

return 0;
}

/////////////////////////////////END CODE///////////////////////////

I know that this does not work but what I want to do is to write the
f() function in such a way the pointer returns whatever value it is
asked and the function declaration cannot change. The output should be
"w = 123456". But this is not the case.

I searched the newsgroups for examples with void* in their arguments
and I found this. I have tried this and it works:

//////////////////////////////////////////CODE//////////////////////
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

long f(int a, void* b) {
float* c;
char* df1;
long q = 123456;
long* df2 = &q;

*(long*)b = q;

return 0;
}

int main() {
long w;

f(2, &w);
printf("w = %u\n", w);

return 0;
}

///////////////////////////////////////////END
CODE///////////////////////////


The output is what I desire: "w = 1234656". But this means that the
function will have to have as one of its arguments a parameter
specifying what the datatype should be. But I cannot change the
function declaration and yet the void* should point to the right data.

Please help.

With best regards,
Mark Antony
 
A

Arthur J. O'Dwyer

Thanks to Jeff and Todd for their reply.
What you told me is correct. But I want to do something like this:
long f(int a, void* b) {
float* c;
char* df1;
long q = 123456;
long* df2 = &q;

It's not really clear what all these variables are doing here.

A simple
*(long *)b = 123456L;
would do.
return 0;
}

int main() {
long w;

f(2, &w);

Okay, presumably you're going to expand the above function
so that the first ('int') argument specifies the "real type"
of 'b', and you assign something different to it depending
on the value of the argument.
printf("w = %u\n", w);

Nit: %u should be %ld there, because 'w' is a 'long'.
return 0;
}
I know that this does not work but what I want to do is to write the
f() function in such a way the pointer returns whatever value it is
asked and the function declaration cannot change. The output should be
"w = 123456". But this is not the case.

With the changes '*b'->'*(long*)b' and '%u'->'%ld', it should be
the case. ...And you go on to say that it is. So, good.

[snip slightly-more-correct code]
The output is what I desire: "w = 1234656". But this means that the
function will have to have as one of its arguments a parameter
specifying what the datatype should be. But I cannot change the
function declaration and yet the void* should point to the right data.

Please help.

Well, that's *the* way to do it. You can't use the parameter unless
you know what type it is, and you can't know what type it is unless
you let yourself know. Which means passing information to the
function. Which means:

1) Use a function parameter (recommended).

enum FOO_TYPE { FOO_TYPE_LONG, FOO_TYPE_CPTR, FOO_TYPE_INT };
void foo (enum FOO_TYPE what_type, void *param);

foo(FOO_TYPE_CPTR, "bar");
foo(FOO_TYPE_LONG, &mylong);


2) Use a global variable (icky but probably what you asked for).

static enum FOO_TYPE GlobalFooParamIcky;
void foo (void *param);

GlobalFooParamIcky = FOO_TYPE_CPTR;
foo("bar");
GlobalFooParamIcky = FOO_TYPE_LONG;
foo(&mylong);


3) Use a cutesy method (not recommended unless you are
otherwise seriously considering #2).

void *FOO_TYPE_CPTR = &FOO_TYPE_CPTR;
void *FOO_TYPE_LONG = &FOO_TYPE_LONG;
void *FOO_TYPE_INT = &FOO_TYPE_INT;

void foo (void *param)
{
static int step = 0;
static void *type = NULL;
if (param == NULL) {
step = 1;
return;
}
if (step == 1) {
type = param;
step = 0;
return;
}
if (type == FOO_TYPE_CPTR) {
printf("%s\n", param);
}
else if (type == FOO_TYPE_LONG) {
*(long*)param = 123456L;
}
}

foo(NULL); foo(FOO_TYPE_CPTR); foo("bar");
foo(NULL); foo(FOO_TYPE_LONG); foo(&mylong);


Those are your options. As far as I can tell, they're
basically your *only* options (although alternative
methods are welcome).

I hope one of these helps you.


(e-mail address removed) (Mark Antony) wrote in message


A: Yes.

Q: Even if I'm only quoting myself?

A: Because it's hard to read.

Q: Why do you say not to top-post?

HTH,
-Arthur
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,077
Messages
2,570,566
Members
47,202
Latest member
misc.

Latest Threads

Top