Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    [Solved]Dynamic cast to void pointer

    General and Desktop
    4
    15
    6292
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      ashokb last edited by

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

      // 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...

      1 Reply Last reply Reply Quote 0
      • J
        jafarabadi.qt last edited by

        Hi ashokb
        You have problem in casting or in dynamicCall?

        1 Reply Last reply Reply Quote 0
        • A
          ambershark last edited by

          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.

          My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

          1 Reply Last reply Reply Quote 0
          • A
            ashokb last edited by

            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).

            http://qt-project.org/doc/qt-4.8/qvariant.html#value
            http://qt-project.org/doc/qt-5/qaxbase.html#dynamicCall

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

            1 Reply Last reply Reply Quote 0
            • jeremy_k
              jeremy_k last edited by

              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.

              Asking a question about code? http://eel.is/iso-c++/testcase/

              1 Reply Last reply Reply Quote 0
              • A
                ashokb last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • jeremy_k
                  jeremy_k last edited by

                  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;
                  }@

                  Asking a question about code? http://eel.is/iso-c++/testcase/

                  1 Reply Last reply Reply Quote 0
                  • A
                    ashokb last edited by

                    Hi

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

                    qDebug Output:

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

                    Thanks...

                    1 Reply Last reply Reply Quote 0
                    • A
                      ambershark last edited by

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

                      Glad the reinterpret_cast worked for you though.

                      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                      1 Reply Last reply Reply Quote 0
                      • A
                        ashokb last edited by

                        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 *)?

                        1 Reply Last reply Reply Quote 0
                        • jeremy_k
                          jeremy_k last edited by

                          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.

                          Asking a question about code? http://eel.is/iso-c++/testcase/

                          1 Reply Last reply Reply Quote 0
                          • jeremy_k
                            jeremy_k last edited by

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

                            More detail: http://www.cplusplus.com/doc/tutorial/typecasting/

                            Asking a question about code? http://eel.is/iso-c++/testcase/

                            1 Reply Last reply Reply Quote 0
                            • A
                              ashokb last edited by

                              Hi jeremy_k

                              Thanks for useful info and help....

                              1 Reply Last reply Reply Quote 0
                              • A
                                ambershark last edited by

                                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.

                                My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                                1 Reply Last reply Reply Quote 0
                                • A
                                  ashokb last edited by

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

                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post