Announcement

Collapse
No announcement yet.

returning pointers from function

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

  • returning pointers from function

    I have a third party activex control that the com browser created an inc file for. I use a lot of the simple functions with no problem, but can't seem to get multiple parameters back where pointers are involved. The inc file includes the line-

    MEMBER CALL GetWigetDetails <94> (IN AxisIndex AS LONG<0>, IN pRawPos AS VARIANT<1>, IN pField AS VARIANT<2>, IN pAGC AS VARIANT<3>, IN pMagnitude AS VARIANT<4>, IN pTemperature AS VARIANT<5>, IN pStatus AS VARIANT<6>) AS LONG

    I know the parameters are an input, followed by pointers to two longs, a double followed by three more longs. The function returns no error, but whatever variables I try to use, varients etc., my pointers come back empty. What kind of variables and syntax are required to get data back from com objects? And why are the pointers prefixed with IN, when they should return data?

  • #2
    Well, if your code (not shown) is not assigning those variants with...
    Code:
      LOCAL vRawPos AS VARIANT 
      LOCAL dwRawPOS AS DWORD  
    
      LET   vRawPos = BYREF dwRawPos 
    
      OBJECT CALL  O.GetWigetDetails (..., vRawPos, ....)
    ... then those values will not be filled.

    That is, any OUT param must by a BYREF variant with its object being the scalar ("regular") variable you want filled. (I think it can also be a BYREF STRING, too, but I don't think I ever saw that.)

    Can't explain the IN vs OUT in the parameter list. What did you use to generate the INTERFACE definition? (not told).
    Last edited by Michael Mattias; 16 Jun 2009, 04:49 PM.
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      I said, though subtly, the inc file was generated with the com browser (from PBWin9.01), but I think you hit it. I didn't realize I had to specify BYREF, but I'll try that next. Still not a clue why the browser decided that everything should be IN. Would it be common to have to make manual changed to what the com browser generates?

      Comment


      • #4
        I got that "BYREF" here I think, when I could not get an "OPT OUT nRow" param back from ADO.

        I'm just guessing you need BYREF but I don't understand why the INTERFACE came out "IN" Maybe it means "In, a pointer" (which is what a BYREF does). That actually kind of makes sense - it's telling you YOU supply ("input") a pointer. (??????)

        It costs nothing to try; and since it's 'heads you win, tails you break even,' it ain't a bad deal regardless.
        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Still not a clue why the browser decided that everything should be IN.
          The browsers decide according the flags returned by the type library. If the type library is buggy and doesn't return any flag, then it has to choose a default. But there is nothing wrong in returning a value in a variant passed by value if it contains a pointer to a variable. What will be modified will be the referenced variable, not the variant.

          Would it be common to have to make manual changed to what the com browser generates?
          No. When using Automation, if the parameters are VARIANTs, it doesn't matter. What it matters is if the variants have to hold a value or a pointer to a variable, variant or safe array. This is because the parameters aren't pushed into the stack, but used to fill an array of variants. A pointer to this array of variants is what is pushed into the stack in the call to IDispatch.Invoke.

          It does matter when using direct interface calls, because the parameters are pushed into the stack and the method called directly.
          Forum: http://www.jose.it-berater.org/smfforum/index.php

          Comment


          • #6
            Yep Michael, you're the man. I didn't know I had to initialize the variants that way. Works like a champ now- Thanks!

            Comment


            • #7
              I might add that the root of my confusion was a result of thinking that if a pointer was involved, that I would have a pointer variable type defined somewhere, and that the function would return an actual pointer address that I could use in the conventional manner. Essentially once the variant is made equal byref, everything happens behind the scenes. Nothing is actually returned, thus the IN makes perfect sense. Nowhere in my searches is this topic well explained in language even an idiot could understand- a format I find very useful for some reason. :confused2:

              Comment


              • #8
                In the help, under METHOD/END METHOD there is a section called "Direction Attributes" dealing with IN, OUT, INOUT. Also in the PROPERTY/END PROPERTY statement documentation.
                Last edited by Rodney Hicks; 19 Jun 2009, 06:12 AM.
                Rod
                I want not 'not', not Knot, not Knott, not Nott, not knot, not naught, not nought, but aught.

                Comment


                • #9
                  I read those multiple times, but without an overall grasp of how things are supposed to work, they didn't help much. Once I saw the word "pointers" and assumed I'd be using pointer type variables, it was very hard to lose that concept and see what was really happening.

                  Comment


                  • #10
                    When I was working on that "OUT param" I, too, was a bit confused by how "output parameters" are handled.

                    For most WinAPI calls which return an "out" you pass a variable by reference and it is filled on success. So I thought I could just pass a variant by reference (VT_EMPTY was my first guess) and the method would fill it. Nope, that didn't work.

                    I also learned doing this that the IN, OUT and ARRAY stuff for automation methods does not mean the same thing all the time, and you have to play around with the syntax of the doc to get all the possible interpretations.

                    Fortunately, I had learned to parse sentences multiple ways during the Clinton Administration, so it wasn't that hard.

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

                    Comment


                    • #11
                      Sorry Conrad.
                      I took your statement-
                      Nowhere in my searches is this topic well explained in language even an idiot could understand- a format I find very useful for some reason.
                      and failed to follow what I had learned for different reasons that Michael states-
                      parse sentences multiple ways
                      or I would have seen that you may have found those sections I pointed out.

                      When I read them, they made perfect sense to me, but I have not tried to utilize them at this point.
                      I now know there is another hot spot I'm going to encounter and forewarned is forearmed. (One distinct advantage of being on the trailing edge.)
                      Rod
                      I want not 'not', not Knot, not Knott, not Nott, not knot, not naught, not nought, but aught.

                      Comment


                      • #12
                        Hello,
                        i have problem with BYREF as InOut for Member CALL.

                        How can ByteArray as BYREF VARIANT (as parameter) assign?

                        Code:
                        DIM vArray      AS VARIANT
                        DIM bBytArr(3)  AS BYTE
                        
                        bBytArr(0) = <Byte1>
                        bBytArr(1) = <Byte2>
                        bBytArr(2) = <Byte3>
                        bBytArr(3) = <Byte4>
                        
                        LET vArray = bBytArr()
                        
                        OBJECT CALL ExecuteCommand(..., ..., vArray)  '<-- this does not work!
                        for Member in ...INC
                        Code:
                          Member Call ExecuteCommand <22> (In commandName As String<0>, In parameterDataSize As Word<1>, InOut PB_data As _
                                Variant<2>)
                        Last edited by Alexander Holzer; 26 Jun 2009, 11:10 AM.
                        Yours sincerely

                        Comment


                        • #13
                          See this thread:

                          http://www.powerbasic.com/support/pb...afearraycreate

                          In the call to SafeArrayCreate you will have to use %VT_UI1 instead of %VT_VARIANT, then use BYTE variables instead of variants for the parameters, and @lpv.vt = %VT_ARRAY OR %VT_UI1 OR %VT_BYREF instead of @lpv.vt = %VT_ARRAY OR %VT_VARIANT.
                          Forum: http://www.jose.it-berater.org/smfforum/index.php

                          Comment


                          • #14
                            Originally posted by José Roca View Post
                            See this thread:

                            http://www.powerbasic.com/support/pb...afearraycreate

                            In the call to SafeArrayCreate you will have to use %VT_UI1 instead of %VT_VARIANT, then use BYTE variables instead of variants for the parameters, and @lpv.vt = %VT_ARRAY OR %VT_UI1 OR %VT_BYREF instead of @lpv.vt = %VT_ARRAY OR %VT_VARIANT.
                            Hello Jose,
                            thanks, I try this...

                            for <In> it works fine:
                            Code:
                            DIM vArray      AS VARIANT
                            DIM bBytArr(3)  AS BYTE
                            
                            bBytArr(0) = <Byte1>
                            bBytArr(1) = <Byte2>
                            bBytArr(2) = <Byte3>
                            bBytArr(3) = <Byte4>
                            
                            LET vArray = bBytArr()
                            for <Out> or <InOut> - not. It is necessary only BYREF methode. How it to make, here a question.
                            Last edited by Alexander Holzer; 27 Jun 2009, 06:36 AM.
                            Yours sincerely

                            Comment


                            • #15
                              SQL Server returns a BYTE ARRAY when the selected column is type 'nvarchar' and is not CAST to something else in the SELECT.

                              You might see if the code I developed to handle this with ADO at Generic 'ADO' Connection and Query Tester (CC 5+/Win 9+) 11-02-08 might be adaptable for your purposes.
                              Michael Mattias
                              Tal Systems Inc. (retired)
                              Racine WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                It has nothing to do with ADO. It's a different application and not it's not from microsoft.
                                Yours sincerely

                                Comment


                                • #17
                                  It has nothing to do with ADO. It's a different application and not it's not from microsoft.
                                  A. I should have guessed that from your posted code example
                                  B. I said "adapt from".

                                  You didn't even look at it, much less try it, did you?

                                  Silly me, I suggested working code which handles a BYTE ARRAY returned by a COM server to address your problem of ... returning a byte array from a COM server. I guess I just assumed those might be fairly similar problems.
                                  Michael Mattias
                                  Tal Systems Inc. (retired)
                                  Racine WI USA
                                  [email protected]
                                  http://www.talsystems.com

                                  Comment


                                  • #18
                                    MS C/C++ adapted this automatically and it works. I would like to know, how one realized it in PBWin 9 for COM:
                                    Code:
                                     ....
                                    Member Call ExecuteCommand <22> (In commandName As String<0>, In parameterDataSize As Word<1>, Out PB_data As Variant<2>)
                                    ...
                                    e.g. in C++ this Call
                                    ExecuteCommand(..., ..., ref vArray)
                                    Yours sincerely

                                    Comment


                                    • #19
                                      The only way is using the safe array API functions:

                                      http://msdn.microsoft.com/en-us/library/ms221234.aspx
                                      Forum: http://www.jose.it-berater.org/smfforum/index.php

                                      Comment


                                      • #20
                                        Originally posted by José Roca View Post
                                        See this thread:

                                        http://www.powerbasic.com/support/pb...afearraycreate

                                        In the call to SafeArrayCreate you will have to use %VT_UI1 instead of %VT_VARIANT, then use BYTE variables instead of variants for the parameters, and @lpv.vt = %VT_ARRAY OR %VT_UI1 OR %VT_BYREF instead of @lpv.vt = %VT_ARRAY OR %VT_VARIANT.
                                        Originally posted by José Roca View Post
                                        The only way is using the safe array API functions:

                                        http://msdn.microsoft.com/en-us/library/ms221234.aspx
                                        Thanks, Jose,
                                        but it doesn't work, i try:
                                        ... @lpv.vt = %VT_ARRAY OR %VT_BYREF
                                        and try
                                        ... @lpv.vt = %VT_ARRAY OR %VT_UI1 OR %VT_BYREF
                                        without success

                                        This works fine, but not PBWin code:
                                        Code:
                                        byte[] data = new byte[4];
                                        data[0] = 0x28;
                                        data[1] = 0x64;
                                        data[2] = 0xf5;
                                        data[3] = 0x00;
                                        object dataPointer = (object) data;
                                        ExecuteCommand(..., ..., ref dataPointer);
                                        How to translate into PBWin 9 correctly? :shhh:

                                        Thanks
                                        Yours sincerely

                                        Comment

                                        Working...
                                        X