Announcement

Collapse
No announcement yet.

Passing Variant Array From VB6 To PBWin

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

  • Passing Variant Array From VB6 To PBWin

    The final barrier in finishing my project is to be able to pass a variant array from VB6 to PBWin 10.

    I believe I need a variant array because each element can be a different type: string, long, single, double, byte array.

    Any direction on where to find this type of information would be greatly appreciated. No luck so far.
    Secret News | Mercury | Vaccines | Geoengineering | Utilities Made with PowerBasic

  • #2
    Still can't find an answer about how to pass a variant array from Visual Basic 6 to a PBWin DLL.

    In my research to solve this problem, I came across this reference that may be valuable to others using PB with VB. I hope it helps someone:

    How Visual Basic 6 Stores Data

    Secret News | Mercury | Vaccines | Geoengineering | Utilities Made with PowerBasic

    Comment


    • #3
      Is it safe to pass a variant array from VB to PBWin using pointers to arrays as described here:

      Pointers to arrays

      The example in the documentation talks about different data types and even dynamic arrays but does not mention variant arrays, which I know often have special considerations.
      Secret News | Mercury | Vaccines | Geoengineering | Utilities Made with PowerBasic

      Comment


      • #4
        An array of variants is just an array of 16 byte values. ou should be able to assign any element to a variant variable and then work with it.



        '[code]
        #COMPILE EXE
        #DIM ALL
        #DEBUG ERROR ON
        #DEBUG DISPLAY ON

        FUNCTION PBMAIN() AS LONG
        LOCAL v() AS VARIANT
        LOCAL vs AS VARIANT
        LOCAL vn AS VARIANT
        LOCAL s AS WSTRING
        LOCAL n AS DOUBLE
        REDIM v(2)
        vs = "I am a string in a variant"
        vn = 123.456
        v(1)= vs
        v(2) = vn

        s = VARIANT$(vs)
        n = VARIANT#(vn)
        ? STR$(n) & " " & s
        END FUNCTION

        Comment


        • #5
          Originally posted by Russell Tanner View Post
          Is it safe to pass a variant array from VB to PBWin using pointers to arrays as described here:

          Pointers to arrays

          The example in the documentation talks about different data types and even dynamic arrays but does not mention variant arrays, which I know often have special considerations.
          SInce Variants are just 16 byte values,
          Local v AS VARIANT
          LOCAL pV AS VARIANT POINTER
          v = @pV should work

          Comment


          • #6
            Yep, it worked! Thanks for the response.

            This is what I just tried and it appears to be working. Hopefully I'm not mangling anything or creating memory leaks. I'm not used to working this close to the operating system and memory. This is derived from this documentation.

            VB6 Code:
            Code:
            Private Declare Function VArr_Test Lib "rtSQLite3.dll" (ByRef x As Variant, ByVal Count As Integer) As String
            
            Private Sub cmdTest_Click()
                Dim v() As Variant
                Dim r As String
                ReDim v(1)
                v(0) = "zero"    'Create some strings to return to me.
                v(1) = "one"
                r = VArr_Test(v(0), 2)    'Pass a pointer to the variant array and the element count.
                Debug.Print "Result: " & r    'Print returned string: "zero".
            End Sub
            PBWin 10 Code:
            Code:
            FUNCTION VArr_Test ALIAS "VArr_Test" (BYREF va AS VARIANT, BYVAL ElmCount AS INTEGER) EXPORT AS STRING
               DIM vp AS VARIANT PTR
               DIM s AS STRING
               DIM v AS VARIANT
               vp = VARPTR(va)    'Get pointer to array of variants.
               v = @vp[0]    'Assign to variant. Necessary to avoid type mismatch during compile.
               FUNCTION = VARIANT$(v)    'Return string from first element (element 0).
            END FUNCTION
            Secret News | Mercury | Vaccines | Geoengineering | Utilities Made with PowerBasic

            Comment


            • #7
              Originally posted by Stuart McLachlan View Post

              SInce Variants are just 16 byte values,
              Local v AS VARIANT
              LOCAL pV AS VARIANT POINTER
              v = @pV should work
              How do the strings work? They are 22 bytes.
              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
                Nice, the called PowerBASIC function receives a pointer to first element of the variant array with the count of number of elements.
                Point is, all elements are available to the called function.

                Converting each element (if different types) is the challenge (requirement in post #1.)
                If only passing string arrays JOIN() with VB6 and JOIN$ with PB is a good way to pass them back and forth without conversions.
                Code:
                #COMPILE DLL "rtSQlite3"
                DECLARE FUNCTION VArr_Test LIB "rtSQLite3.dll" (BYREF x AS VARIANT,COUNT AS LONG) AS STRING
                FUNCTION VArr_Test ALIAS "VArr_Test" (BYREF va AS VARIANT,COUNT AS LONG) EXPORT AS STRING
                 LOCAL x AS LONG
                 DIM vp AS VARIANT PTR
                 DIM s AS STRING
                 DIM v AS VARIANT
                 vp = VARPTR(va) 'Get pointer to array of variants.
                 v = @vp[0] 'Assign to variant. Necessary to avoid type mismatch during compile.
                 FOR x = 0 TO COUNT                 'converting back to strings
                  s+= VARIANT$(@vp[x]) + $CR      'don't know if there is a fast way to do this?
                 NEXT
                 FUNCTION = s 'Return all
                END FUNCTION
                CMD shortcut to open any location:
                %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
                Change to run as administrator
                How long is an idea? Write it down.

                Comment


                • #9
                  Originally posted by Kurt Kuzba View Post

                  How do the strings work? They are 22 bytes.
                  What strings? An array of variants is an array of 16 byte values. Each of which contains a pointer to something which may be a number, string, another array etc.

                  Comment


                  • #10
                    One thing you should try is accepting the variant passed by VB as a simple VARIANT datatype.

                    Then use VARIANTVT () or maybe better still, this more comprehensive version of same
                    Get VARIANTVT literal

                    I'm thinking that will come back as "VARIANT ARRAY" (the PB VARIANTVT function cannot handle this) at which point asI recall you should be able to..
                    Code:
                      LOCAL v AS VARIANT
                      LOCAL va() AS VARIANT
                    
                    
                      REDIM va(0)
                      v =  however the value is passed to you (procedure paranm?)
                      va() = V                  ' assign variant to the array
                    You might have to size the va() array bigger to start... it's been a long time since I did this and darned if I can even remember where. I think, however, whatever I was doing at the time is what caused me to create that function linked above.

                    But instead of VARIANT ARRAY it might come back as "STRING ARRAY" or WSTRING ARRAY" or something else in which case you create your PB array as the correct datatype instead of as a variant... and the assignment statement will handle everything,

                    It's a thought.

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

                    Comment


                    • #11
                      Originally posted by Stuart McLachlan View Post

                      What strings? An array of variants is an array of 16 byte values. Each of which contains a pointer to something which may be a number, string, another array etc.
                      Well, I don't know. That's why I asked. The info on Microsoft website says:
                      "Variables declared as the Variant data type can contain string, date, time, Boolean, or numeric values, and can convert the values that they contain automatically. Numeric Variant values require 16 bytes of memory ... and they are slower to access than explicitly typed variables of any other type. You rarely use the Variant data type for a constant. String Variant values require 22 bytes of memory."
                      Where do they have the extra six bytes?
                      The world is strange and wonderful.*
                      I reserve the right to be horrifically wrong.
                      Please maintain a safe following distance.
                      *wonderful sold separately.

                      Comment


                      • #12
                        Originally posted by Kurt Kuzba View Post

                        Well, I don't know. That's why I asked. The info on Microsoft website says:
                        "Variables declared as the Variant data type can contain string, date, time, Boolean, or numeric values, and can convert the values that they contain automatically. Numeric Variant values require 16 bytes of memory ... and they are slower to access than explicitly typed variables of any other type. You rarely use the Variant data type for a constant. String Variant values require 22 bytes of memory."
                        Where do they have the extra six bytes?
                        Got a link? I'd need to read the full page.

                        Comment


                        • #13
                          If you are referring to this site: https://docs.microsoft.com/en-us/off...a-type-summary
                          or similar, that 22 bytes is NOT the Variant pointer. It is part of the size in memory required to store the actual data and wrapper.


                          "The following table shows the supported data types, including storage sizes and ranges." [emphasis added]
                          Variant (with characters) 22 bytes + string length (24 bytes on 64-bit systems) Same range as for variable-length String

                          Comment


                          • #14
                            Variants in PB are 16 bytes.
                            The VARIANT has 8 bytes for the data. If the data can't fit into the 8 bytes then the VARIANT contains a pointer to the data instead.

                            If a string is contained in a VARIANT then the VARIANT contains the 4 byte pointer to the WIDE string's location in memory.

                            Comment


                            • #15
                              Here is what Mr. Zale said about string array in a variant:
                              https://forum.powerbasic.com/forum/u...eaks-poke-peek
                              CMD shortcut to open any location:
                              %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
                              Change to run as administrator
                              How long is an idea? Write it down.

                              Comment


                              • #16
                                Originally posted by Mike Doty View Post
                                Here is what Mr. Zale said about string array in a variant:
                                https://forum.powerbasic.com/forum/u...eaks-poke-peek
                                All I see in that thread is "Using a variant as temporary storage for an array is extraordinarily inefficient since it requires creation of a SafeArray. Avoid it like the plague."

                                which has no relevance to this thread since this one is discussing passing variants, incuding variants which are arrays of variants, between PB and applications written in toher languages (specifically VB6 in this case"Nothing at all about using variants as temporary sotrage for PB arrays.

                                It's also worth pointing out that he wrote that before the advent of iPowerArray which makes using variants and safearraysmuch more efficient (see MoveFormVAriant and MoveToVariant methods)

                                Comment

                                Working...
                                X