QVariant wrapped pointers turn to null in QML - c++

It seems like something is going wrong when pointer values transcend between C++ and QML world. I am using the plain old fromValue() and value() to convert to and from void *, and it does work as expected as long as the variant stays on the C++ side.
The moment it is returned to QML, it now resolves to null, and when passed back to C++, the variant type is changed from void * to std::nullptr_t and the value is null.
returning 0x3ba5b10 // created
converting to qvariant 0x3ba5b10 // converting
converted QVariant(void*, 0x3ba5b10) 0x3ba5b10 // now variant, testing value() - all good
qml: null // in qml
received QVariant(std::nullptr_t, (nullptr)) 0x0 // back in c++
I am using:
Q_DECLARE_METATYPE(void*)
qRegisterMetaType<void*>();
Any clue as to what is going on here?
Edit: it keeps even more strange, I get it to work by casting the pointer values to 64 bit uint and back, but upon the transition to QML, the type info gets messed up, in C++ the variant is of type qulonglong, arriving back from QML it is now a double, hence the suspicion it might round something and mess up the pointer value.
Edit 2: note that the question is not about recommending practices but about why this doesn't work as expected and observed prior to reaching QML.

You don't need to register void*, rather use the metatype QMetaType::VoidStar.
Note that to register the metatype SomeCustomType*, you need to use an alias.
using SomeCustomTypePtr = SomeCustomType*;
Q_DECLARE_METATYPE(SomeCustomTypePtr)
qRegisterMetaType<SomeCustomTypePtr>();

Isn't even possible to do such declarations?
According to official documentation on Q_DECLARE_METATYPE(Type):
This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.
This macro requires that Type is a fully defined type at the point where it is used.
Sounds strange that this works at least in C++ part.
Don't you think that it will be better and straight-forward solution to declare your type pointer instead of void*?

Related

How to deal with a generic object in C++

What is the proper way to deal with a generic value in C++11 or is it OK to use (void *)?
Basically, I am parsing json, and the node value can either be String, Integer, Double, Date, etc.
In C, just using void * is OK (not safe, but ok), and in C# we use Object. But what is the proper way in C++11 to do this? Do I have to build a wrapper class, or is there an easier way?
You can make a base class for the various types, or use a "discriminated union" class such as Boost.Variant which holds a known set of types and remembers which one it is holding.

Is there a way to have a function return a type?

I have a data class (struct actually) two variables: a void pointer and a string containing the type of the object being pointed to.
struct data{
void* index;
std::string type;
data(): index(0), type("null"){}
data(void* index, std::string type): index(index), type(type){}};
Now I need to use the object being pointed to, by casting the void pointer to a type that is specified by the string, so I thought of using an std::map with strings and functions.
std::unordered_map<std::string, function> cast;
The problem is that the functions must always have the exact same return-type and can't return a type itself.
Edit:
Because I use the data class as a return-type and as arguments, templates won't suffice.
(also added some code to show what I mean)
data somefunction(data a){
//do stuff
return data();}
Currently, I use functions like this to do the trick, but I thought it could be done more easily:
void functionforstring(data a){
dynamic_cast<string*>(data.index)->function();}
Neither thing is possible in C++:
Functions cannot return types (that is to say, types are not values).
Code cannot operate on objects whose type it doesn't know at compile-time (that is to say, C++ is statically typed). Of course there is dynamic polymorphism via virtual functions, but even with that, the type of the pointer you use to call them is known at compile time by the calling code.
So the operation you want, "convert to the pointer type indicated by a string" is not possible. If it were possible, then the result would be a pointer whose type is not known at compile time, and that cannot be.
There's nothing you could do with this "pointer of type unknown at compile time", that you can't do using the void* you started with. void* pretty much already is what C++ has in place of a pointer to unknown type.
While it's not possible to return a type from a function, you could use typeid to get information about the object, and use the string returned by typeid(*obj).name() as an argument to your constructor.
Keep in mind that this string would be implementation defined, so you would have to generate this string at runtime for every type that you might possibly use in the program in order to make your unordered_map useful.
There is almost certainly a much simpler and more idiomatic way to accomplish your goal in C++, however. Perhaps if you explained more about the goals of the program, someone might be able to suggest an alternative approach.

What are the uses of the type `std::nullptr_t`?

I learned that nullptr, in addition to being convertible to any pointer type (but not to any integral type) also has its own type std::nullptr_t. So it is possible to have a method overload that accepts std::nullptr_t.
Exactly why is such an overload required?
If more than one overload accepts a pointer type, an overload for std::nullptr_t is necessary to accept a nullptr argument. Without the std::nullptr_t overload, it would be ambiguous which pointer overload should be selected when passed nullptr.
Example:
void f(int *intp)
{
// Passed an int pointer
}
void f(char *charp)
{
// Passed a char pointer
}
void f(std::nullptr_t nullp)
{
// Passed a null pointer
}
There are some special cases that comparison with a nullptr_t type is useful to indicate whether an object is valid.
For example, the operator== and operator!= overloads of std::function could only take nullptr_t as the parameter to tell if the function object is empty. For more details you could read this question.
Also, what other type would you give it, that doesn't simply re-introduce the problems we had with NULL? The whole point is to get rid of the nasty implicit conversions, but we can't actually change behaviour of old programs so here we are.
The type was introduced to avoid confusion between integer zero and the the null memory. And as always cpp gives you access to the type. Where as Java only gives you access to the value. It really doesnt matter what purpose you find for it. I normally use it as a token in function overloading.
But I have some issues with the implementation of cpp null const.
Why didnt they just continue with NULL or null? That definition was already being used for that purpose. What about code that already was using nullptr for something else.
Not to mention nullptr is just too long. Annoying to type and ugly to look at most times. 6 characters just to default initialize a variable.
With the introduction of nullptr, you would think zero would no longer be both a integer and null pointer const. However zero still holds that annoying ambiguity. So I dont see the sense then of this new nullptr value. If you define a function that can accept an integer or a char pointer, and pass zero to that function call, the compiler will complain that it is totally ambigious! And I dont think casting to an integer will help.
Finally, it sucks that nullptr_t is part of the std namespace and not simply a keyword. Infact I am just learning this fact, after how long I have been using nullptr_t in my functions. MinGW32 that comes with CodeBlocks allows you to get away with using nullptr_t with std namespace. Infact MinGW32 allows void* increment and a whole lot of other things.
Which leads me to: cpp has too much denominations and confusion. To the point where code compatibility with one compiler is not compatibility with another of the same cpp version. Static library of one compiler cannot work with a different compiler. There is no reason why it has to be this way. And I think this is just one way to help kill cpp.

Obtain void* pointer to content of boost::any

I am using an external library that has a method which accepts a void*
I want this void* to point to an object contained within a boost::any object.
Is it possible to get at the address of the content of a boost::any object?
I'm trying to play with myAny.content but no luck so far! I'm hoping some combination of dynamic_cast or unsafe_any_cast will give me what I need.
Thanks!
You can use boost::any_cast to get a pointer to the underlying type (provided you know it at compile time).
boost::any any_i(5);
int* pi = boost::any_cast<int>(&any_i);
*pi = 6;
void* vpi = pi;
This isn't possible, unfortunately; boost::any_cast will refuse the cast if the type is distinct from the contained type.
If you're willing to use an unsupported internal hack, the current version of the header has an undocumented and unsupported function boost::unsafe_any_cast which (as its name suggests) bypasses the type check performed by boost::any_cast:
boost::any any_value(value);
void *content = boost::unsafe_any_cast<void *>(&any_value);
The header has this to say about unsafe_any_cast:
// Note: The "unsafe" versions of any_cast are not part of the
// public interface and may be removed at any time. They are
// required where we know what type is stored in the any and can't
// use typeid() comparison, e.g., when our types may travel across
// different shared libraries.

Accessing a Pointer to a pointer in C++

Hi I am using a 3rd party library in my iPhone application that uses C++ one of the methods i need to use returns a pointer to a pointer of a class. like follows.
DLL classAttributes** getAttributes();
I can successfully call the method and return the value into a pointer to a pointer like so;
classAttributes **attributes = cPPClass->getAttributes();
however i can't seem to access any of the methods on the class for example i know that the class has a function called getName(); but when i try calling it i get errors.
attributes->getName(); 'Request for member 'getName' in *attributes'; which is of non-class type 'attributes*''
I did some googling and found some stuff that said to access a pointer pointer address use the format
&(*attributes)->getName(); 'invalid uses of incomplete type 'struct attributes'
Any help would be much appreciated.
Thanks.
'invalid uses of incomplete type 'struct attributes' indicates that you need to #include the header file for it. It's only forward-declared at this point in your code.
What you probably want is a classAttributes*. Since you have a classAttribues** , you want to dereference it once to get to the classAttributes*.
(*attributes)
From there you can probably call the members of the class.
classAttributes **attributesArray = cPPClass->getAttributes();
classAttributes *attributesObject(*attributesArray);
attributesObject->getName();
First consider what you would do if the function returned a pointer to a classAttributes variable. In this case, you would simply do:
attributes->getName();
Since it's a pointer to a pointer, you must first dereference it and then use the -> operator:
(*attributes)->getName();
If this doesn't work, it may be a problem caused by the function not being implemented or by inheritance.
Without knowing more about the library, it's hard to say. But it could be returning an array of items:
attributes[0]->getName();
attributes[1]->getName();
The questionable part about my guess, though, is that there is no obvious way to know how many items there are.
By the looks of it, you'd probably have to do is this way (i.e. no ampersand):
(*attributes)->getName();
This is because dereferencing it once will give you a pointer to a struct, on which you can then use the -> operator. What's happening when you do &(*attributes) is that you're dereferencing the pointer, then getting the address of the object you have — in effect making it a no-op.