473,378 Members | 1,346 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

distinguishing wheter void* ptr points to class A or class B?


Hello!

I have some legacy C code which expects a pointer to a function to
be evaluated at one point.
Because of the pointer-to-function vs. pointer-to-member
incompatibility, this needs to be a
global function. To aid the passing of some extra data to the
function, it takes an extra
parameter of type void* which is passed uninterpreted to it.

I am in a situation where this void* pointer can point either to
class A or to a class B,
which are not related. Is there a way to perform a reliable cast in
the function or otherwise
distinguish which the void* pointer actually points to? This is
compiled as C++.
I can static_cast<to whatever, but, obviously, if I get the class
wrong, this segfaults
at the first dereference of a member. dynamic_cast<does not work on
void*.

Is there a way out? I can modify classes A and B at will and the
function in question,
but its signature must remain intact.

TIA,
- J.

Sep 22 '07 #1
6 1854
I have some legacy C code which expects a pointer to a function to
be evaluated at one point.
Because of the pointer-to-function vs. pointer-to-member
incompatibility, this needs to be a
global function. To aid the passing of some extra data to the
function, it takes an extra
parameter of type void* which is passed uninterpreted to it.

I am in a situation where this void* pointer can point either to
class A or to a class B,
which are not related. Is there a way to perform a reliable cast in
the function or otherwise
distinguish which the void* pointer actually points to? This is
compiled as C++.
I can static_cast<to whatever, but, obviously, if I get the class
wrong, this segfaults
at the first dereference of a member. dynamic_cast<does not work on
void*.

Is there a way out? I can modify classes A and B at will and the
function in question,
but its signature must remain intact.
I'm not really sure whether this is valid, but I would try to define
some class C as:

class C
{
public:
virtual int getType() =0;
};

And have A and B inherit from C; then, cast your void* to C* (this is
what I'm not sure about whether it is valid to do), query for the type,
and proceed accordingly.

cheers,
Daniel
--
Got two Dear-Daniel-Instant Messages
by MSN, associate ICQ with stress--so
please use good, old E-MAIL!
Sep 22 '07 #2
Daniel Kraft wrote:
class C
{
public:
virtual int getType() =0;
};

And have A and B inherit from C; then, cast your void* to C* (this is
what I'm not sure about whether it is valid to do), query for the type,
and proceed accordingly.
Once you have a common polymorphic ancestor you can also use
dynamic_cast or typeid.
Sep 22 '07 #3
On Sep 22, 6:27 am, jacek.dzied...@gmail.com wrote:
I have some legacy C code which expects a pointer to a function to
be evaluated at one point.
Because of the pointer-to-function vs. pointer-to-member
incompatibility, this needs to be a
global function. To aid the passing of some extra data to the
function, it takes an extra
parameter of type void* which is passed uninterpreted to it.

I am in a situation where this void* pointer can point either to
class A or to a class B,
which are not related. Is there a way to perform a reliable cast in
the function or otherwise
distinguish which the void* pointer actually points to? This is
compiled as C++.
I can static_cast<to whatever, but, obviously, if I get the class
wrong, this segfaults
at the first dereference of a member. dynamic_cast<does not work on
void*.
You could simple define a small structure with a type tag and a
pointer:

struct C {
int type;
void *ptr; // to either an object of class A or class B
}

When you create the structure, modify the type field accordingly so
that it can be read back once you have to determine what class the
objects belong to. After that, it's just a simple static_cast<of the
'ptr' member.

Sep 22 '07 #4
On Sep 22, 11:48 am, "Alf P. Steinbach" <al...@start.nowrote:
* Justin.SpahrSumm...@gmail.com:
On Sep 22, 6:27 am, jacek.dzied...@gmail.com wrote:
I have some legacy C code which expects a pointer to a function to
be evaluated at one point.
Because of the pointer-to-function vs. pointer-to-member
incompatibility, this needs to be a
global function. To aid the passing of some extra data to the
function, it takes an extra
parameter of type void* which is passed uninterpreted to it.
I am in a situation where this void* pointer can point either to
class A or to a class B,
which are not related. Is there a way to perform a reliable cast in
the function or otherwise
distinguish which the void* pointer actually points to? This is
compiled as C++.
I can static_cast<to whatever, but, obviously, if I get the class
wrong, this segfaults
at the first dereference of a member. dynamic_cast<does not work on
void*.
You could simple define a small structure with a type tag and a
pointer:
struct C {
int type;
void *ptr; // to either an object of class A or class B
}
When you create the structure, modify the type field accordingly so
that it can be read back once you have to determine what class the
objects belong to. After that, it's just a simple static_cast<of the
'ptr' member.

Uhm, well.

In C++ it's usually ungood to explicitly discriminate on type, when a
virtual function can do that type-discrimination.

Here's one way to Do Things (off the cuff, not compiled):

typedef void (*CCallbackFunc)( void* );
typedef void (*CFuncThatCallsBack)( CCallbackFunc, void* );
void generalCallback( void* );

struct AbstractCallbackHandler
{
virtual void onCallback() = 0;
void* pointer() { return this; }
invoke( CFuncThatCallsBack f ) { f( generalCallback, pointer(); }
Seems like you forgot a paren here.
};

CCallBackFunc generalCallBack( void* arg )
I think you meant "void", not "CCallBackFunc".
{
static_cast<AbstractCallbackHandler*>( arg )->onCallback();
}

template< class T void callbackFor( T& o );

template< class T >
struct CallbackHandler
{
T* p;
CallbackHandler( T& o ): p( &o ) {}
virtual void onCallback() { callbackFor( *p ); }
}

// ... code specific to using classes A and B:

template<callbackFor<A>( A& aha ) { ... }
template<callbackFor<B>( B& boo ) { ... }

extern "C" void someCFunc( CCallBackFunc callBackFunc, void* arg );

struct A {};
struct B {};

void doThingsTo( A& a )
{
CallbackHandler<A>( a ).invoke( someCFunc );
}
All of the code you gave took me a hell of a long time to parse... I
personally would opt for the simple and transparent structure. That
said, I couldn't have come up with the code you gave in a million
years... it's very clever.

Sep 22 '07 #5
Ron Natalie wrote:
Daniel Kraft wrote:
>class C
{
public:
virtual int getType() =0;
};

And have A and B inherit from C; then, cast your void* to C* (this is
what I'm not sure about whether it is valid to do), query for the type,
and proceed accordingly.
Once you have a common polymorphic ancestor you can also use
dynamic_cast or typeid.
You could use dynamic_cast on A* and B*. But you cannot use dynamic_cast to
get from void* to C*.
Best

Kai-Uwe Bux
Sep 22 '07 #6
"Daniel Kraft" <d@domob.euschrieb im Newsbeitrag
news:fd**********@newsreader2.utanet.at...
> I have some legacy C code which expects a pointer to a function to
be evaluated at one point.
Because of the pointer-to-function vs. pointer-to-member
incompatibility, this needs to be a
global function. To aid the passing of some extra data to the
function, it takes an extra
parameter of type void* which is passed uninterpreted to it.

I am in a situation where this void* pointer can point either to
class A or to a class B,
which are not related. Is there a way to perform a reliable cast in
the function or otherwise
distinguish which the void* pointer actually points to? This is
compiled as C++.
I can static_cast<to whatever, but, obviously, if I get the class
wrong, this segfaults
at the first dereference of a member. dynamic_cast<does not work on
void*.

Is there a way out? I can modify classes A and B at will and the
function in question,
but its signature must remain intact.

I'm not really sure whether this is valid, but I would try to define some
class C as:

class C
{
public:
virtual int getType() =0;
};

And have A and B inherit from C; then, cast your void* to C* (this is what
I'm not sure about whether it is valid to do), query for the type, and
proceed accordingly.
In practice it probably works, but the original pointer, either to an
instance of A or B, must be cast to C* before the result of this cast is
converted to void*. Otherwise problems might occure when multiple
inheritance is used.

Heinz
Sep 23 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Xavier Decoret | last post by:
This is a compiler error that I get when I try to do: void* p; unsigned int stride; // ... p += stride; I have good reason to do this, namely an iterator over an array of object whose...
27
by: Maximus | last post by:
Hi, I was just wondering, is it good to use return without arguments in a void function as following: void SetMapLayer() { if( !Map ) return; layer = LAYER_MAP; }
5
by: trying_to_learn | last post by:
Hello All Have another qn from the practice exercises. I ve done the exercise and the birds fly member fn was called successfully. But i still cant answer the authors qn. why this ability to...
16
by: He Shiming | last post by:
Hi, I'm having a little bit of trouble regarding pointer casting in my program. I don't understand why the following two cases produce different results. Case 1: IInterface *pInterface = new...
6
by: Pavils Jurjans | last post by:
Hello, Here's the sample XML: <sample1></sample1> <sample2/> From many XML books and online documentations, it is said to be just different syntax for the same data. However, when we...
56
by: maadhuu | last post by:
hello, this is a piece of code ,which is giving an error. #include<stdio.h> int main() { int a =10; void *p = &a; printf("%d ", *p ); //error....why should it //be an error ?can't the...
3
by: vijay.gandhi | last post by:
Hi, I am trying to convert some unmanaged code (C++) to managed code (using C++/CLI). 1) One of the functions used returns a void* which I need to cast into a handle of a managed object. Can...
13
by: Jay Dee | last post by:
Hi all, I am slightly confused about an odd result that douse not create an error, but also douse not give the result I would expect. My aim was to output data to a text file. If the data...
26
by: tjhnson | last post by:
Hi, With properties, attributes and methods seem very similar. I was wondering what techniques people use to give clues to end users as to which 'things' are methods and which are attributes. ...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.