Announcement

Collapse
No announcement yet.

Oop

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

  • Oop

    It appears that a method in pb objects can't accept an array as an imput parameter. Is this correct?

    Code:
    CLASS GSDATA
      INTERFACE CFG
      INHERIT IUNKNOWN
    
    '/---------------------------------------------------------------------------------------------/'
    '/---------------------------------------------------------------------------------------------/'
    
      METHOD Fetch(BYVAL FName AS STRING, CfgStr() AS STRING)  '<---produces error 422 "expected scalar variable
    
      LOCAL NumLines AS LONG
    
      IF DIR$(FName$) = "" THEN
        ERASE CfgStr$()
        EXIT METHOD
      END IF
    
      OPEN FName$ FOR INPUT AS #1
      FILESCAN #1, RECORDS TO NumLines
      REDIM CfgStr$(1 TO NumLines)
      LINE INPUT #1, CfgStr() TO NumLines
      CLOSE #1
    
      END METHOD
    
    '  METHOD Modify(BYVAL FileName AS STRING, CfgStr() AS STRING)
      END METHOD
    
      END INTERFACE
    END CLASS
    Walt Decker

  • #2
    Yep, AFAIK Scalar variable or Variant!

    You can pass the array as a Variant, but to get it as an array in the method, you will need to know its bounds to create a compatible array to work with inside your Class

    Code:
          METHOD Fetch(BYVAL FName AS STRING, vCfgStr AS VARIANT,lngCfgStrLBd AS LONG, lngCfgStrUBd AS LONG)
    
          LOCAL CfgStr() AS STRING
          REDIM CfgStr(lngCfgStrLBd,lngCfgStrUBd)
          CfgStr() = vCfgStr
          ...

    Comment


    • #3
      It appears that a method in pb objects can't accept an array as an imput parameter. Is this correct?
      Yes, correct. Arguments must be COM-compatible data types (this is in the doc somewhere) and PB Arrays are NOT COM-compatible types (they are not on the list) .

      HOWEVER..

      you MAY pass a variant data type argument, and you may assign a PB string array TO a variant data type.

      Conversion of this suggestion into working program code left as exercise for user.

      MCM



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

      Comment


      • #4
        We posted at the same time.

        However..
        you can pass the array as a Variant, but to get it as an array in the method, you will need to know its bounds to create a compatible array to wor with inside your Class..
        You may query the bounds of a safearray held in a variant data type.

        See your WinAPI folder file VBAPI32.INC for a number of handy functions for use with safearrays. (vbArrayLbound and vbArrayUbound() will be of specific interest)

        You might also find this code handy if you are going to play with VARIANT data types.... Get VARIANTVT literal ... that shows you how to use the bit masks for arrays and/or get the data types.
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          > Yep, Scalar variable of Variant!

          FWIW, a VARIANT is not a scalar. But that's not your fault thinking it is, given the way the PB doc was written. I'm afraid PowerBASIC Inc. will once again not be on my ballot for any of this year's Pulitzer Prizes.

          (Scalar = value of variable is at the address of the variable. In a variant, the address of the variable is the address of a structure and does not contain the value of the data. STRING, WSTRING, and arrays and interface variable types are all non-scalar. )

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

          Comment


          • #6
            Originally posted by Michael Mattias View Post
            > Yep, Scalar variable of Variant!

            FWIW, a VARIANT is not a scalar.
            MCM
            Too quick, you are!

            Typo, which I corrected as soon as I spotted it. It now correctly reads "or Variant"

            Comment


            • #7
              Thanks, folks.

              That's why I could not find one method in my snippets of oop that passed an array name; only pointers to an array (although passing an array name is actually passing a pointer).

              That adds additional code. Don't feel like dealing with that now.
              Walt Decker

              Comment


              • #8
                Originally posted by Michael Mattias View Post

                You may query the bounds of a safearray held in a variant data type.

                See your WinAPI folder file VBAPI32.INC for a number of handy functions for use with safearrays. (vbArrayLbound and vbArrayUbound() will be of specific interest)
                Sorry, you've lost me.

                If I do this:
                Code:
                Local v as VARIANT
                Dim strA(1 to 10)
                v = strA()
                then pass v to a class method, what value would I pass for psa in the method when calling this function:
                "FUNCTION vbArrayLBound (BYVAL psa AS DWORD, BYVAL nDim AS INTEGER) AS LONG"

                (If I wanted to work with a safearray, wouldn't it be easier to use a PowerArray in the first place? )


                Comment


                • #9
                  (although passing an array name is actually passing a pointer).
                  But the pointer is not to the data. It points to a header, so not scalar! ((Also not passing the array name. BYREF passes the pointer to the array identified by that name IN SOURCE CODE. ))
                  Dale

                  Comment


                  • #10
                    But the pointer is not to the data.
                    That is irrelevant in a PB sub or function. However; if one passes a pointer to an array as a method parameter one can create a similar array AT pointer and stuff data into it.
                    Walt Decker

                    Comment


                    • #11
                      That's why I could not find one method in my snippets of oop that passed an array name; only pointers to an array (although passing an array name is actually passing a pointer).
                      But a pointer to what?

                      Many of the examples to which you refer pass a pointer to the FIRST ELEMENT of an array (small a) rather than a pointer to the proprietary descriptor of a PB Array (cap A).

                      If that sounds like a bunch of mumbo-jumbo, then you need to study up a little more.
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Michael:

                        I stated "my oop snippets". I was not referring to those by someone else.

                        I know what is passed when one uses a varb name as an argument. I also know what is passed when one passes a varb byval and byref and how to do it. In short, I'm not confused.
                        Walt Decker

                        Comment


                        • #13
                          How about doing it the easy way?

                          From PB's help file:
                          LET VrntVar = array()

                          An entire PowerBASIC array is assigned to a variant variable. In the case of a string array, PowerBASIC automatically handles Unicode conversions needed for the COM specification. Array assignment is limited to the following data types: BYTE, WORD, DWORD, INTEGER, LONG, QUAD, SINGLE, DOUBLE, CURRENCY, or STRING, as Windows does not support all PowerBASIC data forms.

                          LET array() = vrntvar

                          An entire array is assigned from a variant variable to a PowerBASIC array. In the case of a string array, PowerBASIC automatically handles Unicode conversions. You can not assign an array with more than eight dimensions to a PowerBASIC array.

                          Comment


                          • #14
                            Originally posted by Knuth Konrad View Post
                            How about doing it the easy way?

                            From PB's help file:
                            Knuth, In your sexond assignment, array() must be dimensioned the same as the original array() in your first assignment. Hence my suggestion of passing the bounds as parameters to the method.

                            Also from Help, under "Variant Data Types": "you may assign one Variant value to another Variant variable, or even assign an array contained in a Variant to a compatible PowerBASIC array," A bit of testing revealed that "compatible" means that it must be an array pre-DIMed with the same dimensions

                            I'm still waiting for MCM to explain how he would use vbArrayLBound etc to deteremine the dimensions of the PB array in vrntvar.

                            Comment


                            • #15
                              I'm still waiting for MCM to explain how he would use vbArrayLBound etc to deteremine the dimensions of the PB array in vrntva

                              MCM never said he would do your job for you.

                              BUT... You can get the required 'PSA' value by reading the value in the variant.

                              PB code ==> :
                              Code:
                              LOCAL vStruc AS tagVARIANT
                              LOCAL psa AS DWORD
                              
                                   ' Given: 'V'  VARIANT data type containing an array (see prev link supplied to determine that)
                              
                                 TYPE SET vStruc = v  
                                 LET psa  =  vStruc.SafeArray
                              ....
                              Now all those functions in VBAPI32.INC requiring a "psa" will work just fine


                              FWIW, I only did this for you because PB does not include this in its own documentation.



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

                              Comment


                              • #16
                                Originally posted by Michael Mattias View Post


                                MCM never said he would do your job for you.

                                BUT... You can get the required 'PSA' value by reading the value in the variant.

                                PB code ==> :
                                Code:
                                LOCAL vStruc AS tagVARIANT
                                LOCAL psa AS DWORD
                                
                                ' Given: 'V' VARIANT data type containing an array (see prev link supplied to determine that)
                                
                                TYPE SET vStruc = v
                                LET psa = vStruc.SafeArray
                                ....
                                Now all those functions in VBAPI32.INC requiring a "psa" will work just fine


                                FWIW, I only did this for you because PB does not include this in its own documentation.



                                MCM
                                What's a tagVARIANT? PB10 doesn't recognise it with WIn32API.inc and vbapi32.inc included

                                "Error 524 in C:\PBWin10\samples\VPE-PDF\variantarray.bas(8:021): Undefined TYPE
                                Line 8: LOCAL vStruc AS tagVARIANT "


                                Edit: OK, When it switched to Jose's includes, I got it - it's not in PB's includes.. But then I get


                                Error 482 in C:\PBWin10\samples\VPE-PDF\variantarray.bas(16:023): Data type mismatch
                                Line 16: TYPE SET vStruc = v

                                Which seems logical to me. I gave it a try, but still don't see how this could possibly work.

                                Comment


                                • #17
                                  FWIW, here's my conplete test, using MCM's suggestion:

                                  Code:
                                   'PB 10.04
                                   'using Jose's includes to get the tagVARIANT  definition
                                  #COMPILE EXE
                                  #DIM ALL
                                   #INCLUDE "win32api.inc"
                                   #INCLUDE "vbapi32.inc"
                                  FUNCTION PBMAIN () AS LONG
                                  
                                      LOCAL v AS VARIANT
                                      LOCAL vStruc AS tagVariant
                                      LOCAL psa AS DWORD
                                      DIM strA(1 TO 10) AS STRING
                                      DIM LB AS LONG
                                      DIM UB AS LONG
                                      strA(3) = "Test"
                                      v = strA()
                                      TYPE SET vStruc = v       '<==Error 482 in C:\PBWin10\samples\VPE-PDF\variantarray.bas(16:023):  Data type mismatch
                                      LET psa  =  vStruc.SafeArray
                                      LB = vbArrayLBound (BYVAL psa, BYVAL 0)
                                      UB = vbArrayUBound (BYVAL psa, BYVAL 0)
                                      ? USING$("#     #  ",LB,UB)
                                  END FUNCTION
                                  ISTM, that you think that psa is a VARIANT TYPE ID. AFAICT, it is a pointer to the variant itself. (which I assume would need to be a SafeArray ( psa = pointer safe array? )

                                  Comment


                                  • #18

                                    [quote]
                                    Code:
                                    TYPE SET vStruc = v '<==Error 482 in C:\PBWin10\samples\VPE-PDF\variantarray.bas(16:023): Data type mismatch
                                    [quote]

                                    Well,that SHOULD have worked, I think.

                                    You can try...
                                    [code]
                                    LSET vStruc = v
                                    ' or more simply
                                    vStruc = v

                                    [code] ..

                                    but if TYPE SET fails then those "probably" will, too.

                                    SO I'd probably go with
                                    Code:
                                     LOCAL pVAR as VARIANT PTR
                                      pVAR  =  VARPTR (V)
                                      vStruc =  @pVAR
                                       (continue)
                                    Or maybe use a absolute array ..
                                    Code:
                                         REDIM vStruc(0) AS tagVariant AT VAPTR (v)
                                        psa = vStruc(0).SafeArray
                                       ERASE vStruc()
                                    That absolute array technique should work just fine although if you don't work with absolute arrays much it may seem a bit cryptic.

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

                                    Comment


                                    • #19

                                      OK, I gave it a try

                                      LOCAL pVAR as VARIANT PTR
                                      pVAR = VARPTR (V)
                                      vStruc = @pVAR (continue)


                                      Error 482 in C:\PBWin10\samples\VPE-PDF\variantarray.bas(21:013):
                                      Data type mismatch Line 21:

                                      vStruc = @pVAR
                                      REDIM vStruc(0) AS tagVariant AT VARPTR (v)
                                      psa = vStruc(0).SafeArray
                                      ERASE vStruc()


                                      Error 530 in C:\PBWin10\samples\VPE-PDF\variantarray.bas(20:021): Invalid member name/definition
                                      Line 20: psa = vStruc(0).SafeArray

                                      Comment


                                      • #20
                                        Code:
                                         'PB 10.04
                                         'using Jose's includes
                                        #COMPILE EXE
                                        #DIM ALL
                                        #INCLUDE "win32api.inc"
                                        
                                        FUNCTION PBMAIN () AS LONG
                                        
                                            LOCAL v AS VARIANT
                                            LOCAL pv AS tagVariant PTR
                                            LOCAL psa AS DWORD
                                            DIM strA(1 TO 10) AS STRING
                                            DIM LB AS LONG
                                            DIM UB AS LONG
                                            strA(3) = "Test"
                                            v = strA()
                                            pv = VARPTR(v)
                                            psa = @pv.parray
                                            SafeArrayGetLBound psa, 1, LB
                                            SafeArrayGetUBound psa, 1, UB
                                            ? USING$("#     #  ",LB,UB)
                                        
                                        END FUNCTION
                                        Forum: http://www.jose.it-berater.org/smfforum/index.php

                                        Comment

                                        Working...
                                        X