Important: Please read the Qt Code of Conduct -

[Solved]Dynamic cast to void pointer

  • Hi,
    I am using LiteCAD activex in my application. I am calling its methods as follows,
    // Generate drawing
    bool isDraw = axControl->dynamicCall("DrwNew()").toBool();

    // Get default block from drawing
    hBlock = axControl->dynamicCall("DrwGetFirstObject(int)", QVariant(5)).value<void *>();

    // Convert hBlock to QVariant
    QVariant temp = qVariantFromValue((void *) hBlock);

    //add line
    axControl->dynamicCall("BlockAddLine( HANDLE, 0,0, 50,50 )", hBlock);

    //draw all objects
    axControl->dynamicCall("DrwRegenViews(HANDLE)", hBlock);

    hBlock is defined as HANDLE (HANDLE is like a void *).

    I am getting hBlock from "DrwGetFirstObject(int)" this method, and i want to pass it to another method.

    Now the problem is after executing this
    hBlock = axControl->dynamicCall("DrwGetFirstObject(int)", QVariant(5)).value<void *>();

    there is zero in hBlock. If i omit value<void *> then i get some int number in QVariant. That means there is something wrong in type casting, but i don't know what ?

    Then i tried passing qVariant as it is to next function. But there i got error from activex as "Non-optional parameter missing", where as i am passing all parameters.

    I am doing some basic mistake, but can't able to figure it out please help...

  • Hi ashokb
    You have problem in casting or in dynamicCall?

  • Moderators

    From the looks of it you are passing a "5" as a void* into dynamicCall. I can't think of any reason why you would want to do that. There is going to be nothing useful at memory address 0x00000005.

    Also, when you do QVariant(5) it is going to be set as an int and not cast into a void* as QVariant "knows" better. So that is why when you remove the void* it gives you an int value.

    I would give you an answer to help you but I don't really understand what the code is supposed to do. What are you trying to do with that QVariant? What is dynamicCall()? Why is dynamicCall modifying hBlock? That seems like something that would cause problems in Windows. Especially if someone didn't free the handle resources.

  • Hi
    a.jafarabadi i have problem with casting.

    Hi ambershark
    I am NOT PASSING 5 as void *.
    // Get default block from drawing
    hBlock = axControl->dynamicCall("DrwGetFirstObject(int)", QVariant(5)).value<void *>();
    In above code actually i am passing 5 as parameter to "DrwGetFirstObject(int)" function which should be a QVariant, and then function suppose to return me a HANDLE (ie void *) of hBlock. It returns me
    QVariant(int, 419171632) if i qdebug return value as it is. I want to store that value as a void * in hBlock hence i am using
    QVariant.value<void *>()
    method to cast into void *.
    The problem is, after executing this line data in hBlock is 0x0 which is not expected.(expected is something like 0x419171632).

    Let me know if still not clear and thanks for replay....

  • For the sake of clarity, try separating the call to QAxBase::dynamicCall() from the call to QVariant::value(). Then verify that the QVariant is valid, at least for development purposes. Finally, cast it to a void pointer, and inspect it again.

    QAxBase::dynamicCall() is documented as returning an invalid QVariant if the call fails, or if the called method doesn't return a value. Maybe something is going wrong prior to the cast.

  • Hi jeremy_k

    I have verified that QVariant is valid. qDebug prints this,
    QVariant(int, 419171632).

    that means dynamic call is working, there is issue with casting.
    So, i have a QVariant and i want to convert it to void *.
    I am doing
    HANDLE hBlock = QVariant.value<void *>;
    where QVariant is QVariant(int, 419171632)
    i get 0x0 in hBlock.

  • Try a reinterpret_cast<void *>

    @#include <cstdio>
    #include <QVariant>

    int main(int argc, char *argv[])
    QVariant var(0x12345678);
    void * ptr1 = var.value<void *>();
    void * ptr2 = reinterpret_cast<void *>(var.value<int>());
    printf("%p %p\n", ptr1, ptr2);
    return 0;

  • Hi

    That works !!!
    value<void *>() still returns zero.

    qDebug Output:

    hBlock:QVariant(int, 418057520)
    ptr1: 0x0
    ptr2: 0x18eb0d30


  • Moderators

    Sorry about the 5 thing, I missed a parenthesis when I was reading the code. :)

    Glad the reinterpret_cast worked for you though.

  • Hi, ambershark
    You should not sorry for that , actually i should sorry for posting some unreadable code.

    1. reinterpret_cast worked for me, but yesterday i was reading about it and found that its dangerous to use.

    2. If using QVariant.value<>() is a correct way to convert QVariant to any other type then why it is not working in my case?

    3. On many forums its recommended not to use reinterpret_cast, then what might be the other way in this case(QVariant to void *)?

  • reinterpret_cast tells the compiler "trust me, I know what I'm doing". There is no other options (that I know of) for transforming to or from void *. Nothing inherits from void *, and it doesn't inherit from anything. There is no inherently meaningful way to convert it to a pointer to a valid object without risking converting it into a pointer to an invalid object.

    Because of it's lack of meaning, arithmetic and dereferencing void * are also meaningless.

    So no, if you don't understand what it is or how it can be used, staying away from both reinterpret_cast and void * is a good idea. The same caveat goes for C-style casting.

  • I was slightly hasty dismissing static_cast<void *>. That works from a pointer to void *, and back again.

    More detail:

  • Hi jeremy_k

    Thanks for useful info and help....

  • Moderators

    I agree with what jeremy_k said. I use reinterpret_cast a bit in code. It can be dangerous because it has no type checking. When dealing with void *s though there is rarely any type checking and using reinterpret_cast is just fine. Like jeremy said it is basically telling the compiler you know what is in that data and want it cast to a certain type.

    The "dangerous" part comes in if you are not paying attention as a programmer. If you know for sure your pointer is a valid one of class X then a reinterpret_cast is just fine.

    If you think of it in C style it is the same as saying:

    void myVoid = (void)new MyClass;
    MyClass *c = (MyClass *)myVoid;

    Both of those above examples are the same as reinterpret_cast's in c++. In fact you can use the C style casting method in C++ just fine.

  • Hi
    Got it...
    Thanks to both of you.

Log in to reply