void* in callbacks as reference

B

brianhray

Hello:

I am writing a C interface and was curious how/why a void* can be used
as a reference parameter.

////////////////////////////////////////////////////////////
// WORKS:
// Client1.h
void ExternedSetDoFromCallback(void* (*DoGetFromCallback)());
// Client1.cpp
void* (*ptDoGetFromCallback)() = NULL;
void
ExternedSetDoFromCallback(void* (*DoGetFromCallback)())
{
ptDoGetFromCallback = DoGetFromCallback;
}
void *
DoGetFromCallback()
{
if (ptDoGetFromCallback)
return ptDoGetFromCallback();
return NULL;
}
// Worker1.cpp
void* DoSomethingStatic()
{
return (void *) DoSomething();
}
// Init()
ExternedSetDoFromCallback(DoSomethingStatic);
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// DOES NOT WORK:
// Client1.h
void ExternedSetDoFromCallback(void (*DoGetFromCallback)(void*));
// Client1.cpp
void (*ptDoGetFromCallback)(void*) = NULL;
void
ExternedSetDoFromCallback(void (*DoGetFromCallback)(void*))
{
ptDoGetFromCallback = DoGetFromCallback;
}
void
DoGetFromCallback(void* something)
{
if (ptDoGetFromCallback)
ptDoGetFromCallback(something);
}
// Worker1.cpp
void DoSomethingStatic(void* something)
{
something = DoSomething();
}
// Init()
ExternedSetDoFromCallback(DoSomethingStatic);
////////////////////////////////////////////////////////////

Any explanation or suggestions?

-- Brian Ray (http://kazavoo.com)
 
R

Richard Tobin

I am writing a C interface and was curious how/why a void* can be used
as a reference parameter.

Your files have names suggesting that they're C++ programs, and C
doesn't have anything called "reference parameters". I assume that's
the name C++ uses for call-by-reference; C only has call-by-value.
To get the effect of call-by-reference in C you have to explicitly
pass in a pointer instead of the object itself, and dereference
that pointer in the called function.
void DoSomethingStatic(void* something)
{
something = DoSomething();
}

You need to declare the argument as being of type void **, and
pass in the address of the value you want to change. So change it
to

void DoSomethingStatic(void **something)
{
*something = DoSomething();
}

and change the call to

DoGetFromCallback(void* something)
{
if (ptDoGetFromCallback)
ptDoGetFromCallback(&something);
}

Of course, you presumably want to propagate "something" back up to
the caller of DoGetFromCallback(), so you will have to change its
interface too, so that it takes a void **:

DoGetFromCallback(void **something)
{
if (ptDoGetFromCallback)
ptDoGetFromCallback(something);
}

and change whatever calls that.

-- Richard
 
B

bogdan

Hello:

I am writing a C interface and was curious how/why a void* can be used
as a reference parameter.

////////////////////////////////////////////////////////////
// WORKS:
// Client1.h
void ExternedSetDoFromCallback(void* (*DoGetFromCallback)());
// Client1.cpp
void* (*ptDoGetFromCallback)() = NULL;
void
ExternedSetDoFromCallback(void* (*DoGetFromCallback)())
{
ptDoGetFromCallback = DoGetFromCallback;}void *
DoGetFromCallback()
{
if (ptDoGetFromCallback)
return ptDoGetFromCallback();
return NULL;}// Worker1.cpp
void* DoSomethingStatic()
{
return (void *) DoSomething();}// Init()
ExternedSetDoFromCallback(DoSomethingStatic);
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// DOES NOT WORK:
// Client1.h
void ExternedSetDoFromCallback(void (*DoGetFromCallback)(void*));
// Client1.cpp
void (*ptDoGetFromCallback)(void*) = NULL;
void
ExternedSetDoFromCallback(void (*DoGetFromCallback)(void*))
{
ptDoGetFromCallback = DoGetFromCallback;}void
DoGetFromCallback(void* something)
{
if (ptDoGetFromCallback)
ptDoGetFromCallback(something);}// Worker1.cpp
void DoSomethingStatic(void* something)
{
something = DoSomething();}// Init()
ExternedSetDoFromCallback(DoSomethingStatic);
////////////////////////////////////////////////////////////

Any explanation or suggestions?

-- Brian Ray (http://kazavoo.com)


http://magegame.ru/?rf=626f6764616e
 
J

Jack Klein

Hello:

I am writing a C interface and was curious how/why a void* can be used
as a reference parameter.

I don't think so. I don't know of any compiler that processes files
ending in ".cpp" as C.
////////////////////////////////////////////////////////////
// WORKS:
// Client1.h
void ExternedSetDoFromCallback(void* (*DoGetFromCallback)());
// Client1.cpp
void* (*ptDoGetFromCallback)() = NULL;
void
ExternedSetDoFromCallback(void* (*DoGetFromCallback)())
{
ptDoGetFromCallback = DoGetFromCallback;
}
void *
DoGetFromCallback()
{
if (ptDoGetFromCallback)
return ptDoGetFromCallback();
return NULL;
}
// Worker1.cpp
void* DoSomethingStatic()
{
return (void *) DoSomething();
}
// Init()
ExternedSetDoFromCallback(DoSomethingStatic);

It doesn't work, not in C. That is, it doesn't do what the language
defines because the behavior is undefined. There is no defined
conversion, with or without a cast, between pointer to void and any
type of pointer to function.
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// DOES NOT WORK:
// Client1.h
void ExternedSetDoFromCallback(void (*DoGetFromCallback)(void*));
// Client1.cpp
void (*ptDoGetFromCallback)(void*) = NULL;
void
ExternedSetDoFromCallback(void (*DoGetFromCallback)(void*))
{
ptDoGetFromCallback = DoGetFromCallback;
}
void
DoGetFromCallback(void* something)
{
if (ptDoGetFromCallback)
ptDoGetFromCallback(something);
}
// Worker1.cpp
void DoSomethingStatic(void* something)
{
something = DoSomething();
}
// Init()
ExternedSetDoFromCallback(DoSomethingStatic);
////////////////////////////////////////////////////////////

Any explanation or suggestions?

First suggestion is to ask in comp.lang.c++, down the hall. Second,
if you want to talk about converting between object pointers, which
includes void *, and any kind of function pointers, ask in a compiler
specific group. Neither language defines or supports these
conversions.
 
S

Simon Biber

Jack said:
I don't think so. I don't know of any compiler that processes files
ending in ".cpp" as C.

<OT> Turbo C is a compiler that will process files ending in .cpp as C.
That's mostly because it's not a C++ compiler -- it knows nothing of
C++. It also seems not to mind what its input files have as their
extension (except if the name ends in .obj -- it doesn't like that as it
then expects a compiled object file). If your input source file has
extension .exe, and you don't specify a different executable output
file, then it will happily overwrite your source code with the
executable.</OT>
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top