I'm searching for the most common and robust way to check if a void*
can be convert in a given C++ object type. You can see below some information about the context.
When I define a C API for a DLL, I often use void* to hide the C++ object I use behind (something like below)
typedef void* Instance_t;
int createInstance(Instance_t* pInst);
int processing(Instance_t inst, uint8_t* pBuf, size_t bufLength);
When I createInstance
the code cast
a pointer like that:
int createInstance(Instance_t* pInst)
{
MyClass* ptr = new MyClass();
*pInst = (void*)(ptr);
//.... etc
return 0;
}
But the question is how can we later in all the other C function we define, check if the void*
value we receive is a valid MyClass*
. I think we can't as none of the C++ casting operator is really type safe is that case (even dynamic_cast
).
for now my best solution is to use a C cast (or a reinterpret_cast
) and if everything is ok with a call to a IsValid
function define with MyClass.
Have you a better way to do that check ?
You can't do that, unless you (say) allocate all your MyClass instances from a memory pool, and check the address you get passed is a pointer into to that memory pool. Or maintain a list of valid instances.
However, if you need to pass round an opaque pointer just make the client use
struct MyClass;
typedef struct MyClass *Instance_t;
This will compile cleanly and give you a reasonable amount of peace of mind. As long as you're only using the pointer, the compiler is happy. It's when it dereferences it, the compiler needs to know what the pointer actually points to.
I don't think you can do this, and I don't think you should be doing this. A void *
is just a pointer to some location in memory. Almost by definition, there's no way to know what it points to.
But why are you typecasting everything to void *
's, why not use protected and private methods on your class if you want to prevent users from fiddling with the internals of your class?
There is no way to check that an untyped pointer points to a valid object of any particular type. If you use void*
, you are throwing away type checking. Instead, you could declare the type in the C header, and use a pointer to that (incomplete) type rather than void*
.
struct Instance;
int createInstance(struct Instance** pInst);
int processing(struct Instance* inst, uint8_t* pBuf, size_t bufLength);
Then in C++, you can define and use the class.
// Probably better to use "struct" rather than "class" in case
// some compilers complain about mixing class keys.
struct Instance {
// Whatever
};
int createInstance(Instance** pInst) {
*pInst = new Instance;
// and so on
}
There's no way to determine if a void*
points to a valid C++ class. Unless you've got RTTI enabled then there's no metadata associated with a class, and even then there are plenty of cases in C++ where a void*
isn't pointing to a class. For example:
int x=10;
void *ptr = &x;
Here ptr
is pointing to a raw value. There's no RTTI associated with the integer so how could you query it to determine anything>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With