Announcement

Collapse
No announcement yet.

Casting a void pointer (DWORD)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Casting a void pointer (DWORD)

    Is it possible to type cast a void pointer in PBWIN? The following example shows my situation. I can work around this by transferring the DWORD to a specific UDT pointer type, but many times, I have several different types to work with an this makes for cumbersome code.

    Looking for some new ideas

    thank you

    Code:
    #COMPILE EXE
    #DIM ALL
    
    TYPE UDT_Test
    
    a AS DOUBLE
    b AS LONG
    
    END TYPE
    
    
    TYPE UDT_MyVoidPointers
    
    pU_Void AS DWORD
    
    END TYPE
    
    
    FUNCTION PBMAIN () AS LONG
    
    DIM pU_CastTest AS UDT_Test POINTER
    
    DIM U_MyVoidPointers AS UDT_MyVoidPointers
    DIM U_Test AS UDT_Test
    
    U_Test.a = 1.234#
    U_Test.b = 10101
    
    U_MyVoidPointers.pU_Void = VARPTR(U_Test)
    
    ' This does not work since the DWORD is not defined
    '? str$([email protected]_Void.a)
    
    ' So the answer is to case the DWORD as a specific pointer type
    pU_CastTest = U_MyVoidPointers.pU_Void
    
    ' Now we can dereference
    ? STR$(@pU_CastTest.a) + STR$(@pU_CastTest.b)
    
    END FUNCTION

  • #2
    The extra step is having to DIM a UDT pointer and make the assignement:

    Code:
    ' So the answer is to case the DWORD as a specific pointer type
    pU_CastTest = U_MyVoidPointers.pU_Void

    Comment


    • #3
      Define your pointer as a pointer!

      TYPE UDT_MyVoidPointers
      pU_Void AS UDT_TEST PTR
      END TYPE




      Comment


      • #4
        Unfortunately the concept of a "void pointer" doesn't exist in PB. You have to define a pointer in terms of what it is pointing to.

        Comment


        • #5
          Originally posted by Stuart McLachlan View Post
          Unfortunately the concept of a "void pointer" doesn't exist in PB. You have to define a pointer in terms of what it is pointing to.
          You shouldn't need to.
          If you are interfacing with a C module using a void pointer as an argument or a return value, use LONG.
          The world is strange and wonderful.*
          I reserve the right to be horrifically wrong.
          Please maintain a safe following distance.
          *wonderful sold separately.

          Comment


          • #6
            Sorry, but I didn't understand how this offsets the problem of added lines of code to set the type pointer to a DWORD.

            In the C++ approach this is what I would want to do:


            Code:
            (struct *U_MyVoidPointers).*pU_Void = whatever
            Powerbasic is hamstrung in this sense. That is why I was asking the question.

            The example is simple but I have a case where I have 7 different structures to equate and these require a case select to load the proper one.

            Regards,

            Comment


            • #7
              Originally posted by Dean Schrage View Post
              Sorry, but I didn't understand how this offsets the problem of added lines of code to set the type pointer to a DWORD.

              In the C++ approach this is what I would want to do:


              Code:
              (struct *U_MyVoidPointers).*pU_Void = whatever
              Powerbasic is hamstrung in this sense. That is why I was asking the question.

              The example is simple but I have a case where I have 7 different structures to equate and these require a case select to load the proper one.

              Regards,
              A pointer is just a long.
              In C, the void* is used where you want to be able to cast the pointer to different types.
              If you are receiving void pointer from a C or C++ module, it is an address to some data.
              If you know the data type, then declare a pointer to type and make it equal to the long.
              If you need to provide a void pointer to a C or C++ module, then pass the pointer by value as a long.
              And yes, it is extra lines of code to do this.
              Explicit cast to type is a feature of C and C++.
              The world is strange and wonderful.*
              I reserve the right to be horrifically wrong.
              Please maintain a safe following distance.
              *wonderful sold separately.

              Comment


              • #8
                Have you looked in Help at PEEK and POKE?

                Put the address in a DWORD (or LONG), and tell PEEK or POKE what type variable is being referenced in each instance.

                Using "@" requires the pointer be defined as to the type being pointed to (as string ptr, as long ptr, etc, etc.) because there is no other way to know how many bytes to read or write from/to memory.

                "Hamstrung"? Try non-ambiguous but brief (with "@"), more flexible but less brief (with PEEK/POKE).

                Cheers,
                Dale

                Comment


                • #9
                  Yes, I could extract the number of bytes into the DWORD pointer to access the data but this is a bit messy. But I would need to use a type set command which is yet another line of code. In the end, B pointers work well but there are some limitations not encountered in C.

                  My inquiry was really to see if I was missing something obvious.

                  thanks to all who responded.

                  Comment


                  • #10
                    What I am doing it developing a generic propagation tool. There are different types of objects, like satellites, ground tracking stations, planets, stars etc.. A SAT and GTS are different, have different structures, but share some common elements. So I write this generic function that does something like extract the radius of the parent planet. I don't want to write one function for each type. I want to write it generically. When I call the function, I send in the DWORD pointer to the object structure. On the receiving side of the function, I take the DWORD, derive which type of object it is, and they equate it to an instance of that type. Like this:

                    TYPE SAT > to DWORD generic > call function > take DWORD generic > case select the type of object > selects case SAT in the function > get data, do stuff > exit function

                    It is this extra step I am tying to avoid: take DWORD generic > case select the type of object > selects case SAT in the function

                    Comment


                    • #11
                      Are all the structures the same size? If not, you might add a SIZE field in each structure then select the correct structure based on its size.
                      Walt Decker

                      Comment


                      • #12
                        No they are not. If they were, I could index in the desired byte count and get what I need. I fiddled with Unions of all object types but this really wasn't a solution either.

                        Comment


                        • #13
                          Unfortunately the concept of a "void pointer" doesn't exist in PB.
                          True, but it does not need to.

                          The easiest way to think of a "void PTR" parameter in a procedure call is, "32-bit integer whose meaning is defined by you," unless the documentation for the call says otherwise.

                          I have seen VOID PTR used by some functions which might return different things depending on other call options.

                          Because PB passes by reference as a default,, you can often just pass a variable UNLESS THE DECLARE STATEMENT CALLS OUT SOMETHING "BY VALUE."

                          MCM
                          Michael Mattias
                          Tal Systems Inc. (retired)
                          Racine WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                          • #14
                            Consider the WINAPI. Many of those use structures. Many of the structures have a SIZE component. The API selects the correct structure based on the size of the structure.
                            Walt Decker

                            Comment


                            • #15
                              Originally posted by Dean Schrage View Post
                              What I am doing it developing a generic propagation tool. There are different types of objects, like satellites, ground tracking stations, planets, stars etc.. A SAT and GTS are different, have different structures, but share some common elements. So I write this generic function that does something like extract the radius of the parent planet. I don't want to write one function for each type. I want to write it generically. When I call the function, I send in the DWORD pointer to the object structure. On the receiving side of the function, I take the DWORD, derive which type of object it is, and they equate it to an instance of that type. Like this:

                              TYPE SAT > to DWORD generic > call function > take DWORD generic > case select the type of object > selects case SAT in the function > get data, do stuff > exit function

                              It is this extra step I am tying to avoid: take DWORD generic > case select the type of object > selects case SAT in the function
                              You would have to do that in any language.
                              C would allow explicit cast to type inline, (sat_type-01)vpointer, but you would still have to select for type prior.
                              You will need to have pointer types defined and use explicit assignment to type after selecting a type.
                              One thing to look at is how you know what type of data you are processing, what your switch case branching logic will look like.
                              It may be cleaner to set up modules for each of the data types that will place the data into a common structure or return specific data.
                              It will cost a bit of cpu time and some extra lines of code to do it this way, but that is the cost of using type void.
                              You have to establish a type switch and different data handling must be employed in the calling process module.
                              The world is strange and wonderful.*
                              I reserve the right to be horrifically wrong.
                              Please maintain a safe following distance.
                              *wonderful sold separately.

                              Comment


                              • #16
                                Yeah I see your point. Agree

                                Comment


                                • #17
                                  Since the desired term to extract is at a common byte location, I could create a type that would have this reference which is common to all objects. Wondering again if a union would work. I did some tests. I will report back.

                                  Comment

                                  Working...
                                  X