Announcement

Collapse
No announcement yet.

Handling variants

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

  • Handling variants

    I just tried to work with PB variants first time:
    Code:
    Sub dp (sInp As VARIANT) 'JUST HERE IT FAILS!
    	#IF %DEF(%DEBUGMODE)
    		Local szBuf As Asciiz * 1024
    		szBuf = Variant$(sOut) & $CrLf  'THIS SEEMS TO BE OK??
    		WriteConsole ConHNDL, szBuf, LEN(szBuf), %NULL, %NULL
    	#ENDIF
    END SUB
    Well, as You see I'm trying to avoid nasty inputs like "str$(value)" with the sInp variable. Are variants limited so much or is the type error with sInp simpy caused by a syntax bug in my code?
    Norbert Doerre

  • #2
    Use BYVAL

    Then in the function check the format
    hellobasic

    Comment


    • #3
      What you need to do is change sOut to sInp. I believe ByVal/ByRef is immaterial.

      Bob Zale
      PowerBASIC Inc.

      Comment


      • #4
        >Sub dp (sInp As VARIANT) 'JUST HERE IT FAILS!

        ????????????????

        Won't compile? What's the error message?

        Runs Incorrectly?

        Fails with protection fault?

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

        Comment


        • #5
          The code and error message...

          Here the error message:

          Parameter mismatches definition
          Line 2526: dp sEnvironPath (string variable passed)
          ("dp" is the "debug_print")


          Error message continues:

          Parameter mismatches definition - A parameter used in a call to a procedure does not match (or cannot be converted to) the data type or reference type (BYREF, BYVAL, BYCOPY) found in the procedure declaration/definition.

          This error commonly occurs when attempting to pass the wrong type of variable as a parameter, or parameter order may be incorrect. Often, passing the parameter BYCOPY may resolve the error in a legitimate manner. See CALL for more information.

          Other causes include: passing too few or too many parameters to a Sub/Function, omitting a comma between parameters, and by the inclusion of a space or other illegal character in the middle of a parameter name, etc.

          In some cases, it may be permissible to override the compilers type-checking by passing a pointer to the variable BYVAL, rather than using BYCOPY. For example:

          CALL MySub(BYVAL VARPTR(variable))

          End of error message.
          I tried all possible alternatives with always the same error.


          Here the small test code:

          Code:
          #IF %DEF(%DEBUGMODE)
          	GLOBAL ConHNDL AS DWORD
          #ENDIF
          Declare Sub Debug_Init()
          Declare Sub DP(Inp As variant) 
          Declare Sub Debug_Terminate()
          Sub Debug_Init()
          	#IF %DEF(%DEBUGMODE)
          		AllocConsole
          		ConHNDL = GetStdHandle(%STD_OUTPUT_HANDLE)
          	#ENDIF
          END SUB
          Sub DP(Inp As variant)
          	#IF %DEF(%DEBUGMODE)
          		Local szBuf As Asciiz * 1024
          		szBuf = Variant$(Inp) & $CrLf
          		WriteConsole ConHNDL, szBuf, LEN(szBuf), %NULL, %NULL
          	#ENDIF
          END SUB
          SUB Debug_Terminate()
          	#IF %DEF(%DEBUGMODE)
          		FreeConsole
          	#ENDIF
          END SUB
          Norbert Doerre

          Comment


          • #6
            Change Inp to vInp or another name. Inp is a reserved word.
            Forum: http://www.jose.it-berater.org/smfforum/index.php

            Comment


            • #7
              >Inp is a reserved word

              Not in list of reserved words in PB/WIN 8.03 help file.

              If the compiler thinks its a reserved word, either the compiler or the help file is wrong, and in this case it must be the compiler.

              Sure, INP was a function in PB/DOS but there is no INP function in PB/Windows.
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                @Norbert

                Also if you declare the parameter as byref variant then you only can pass a variant, not a string variable or a literal. Declare the parameter as BYVAL vInp AS VARIANT.
                Forum: http://www.jose.it-berater.org/smfforum/index.php

                Comment


                • #9
                  Not in list of reserved words in PB/WIN 8.03 help file.
                  For whatever reason, inp and out are reserved words.
                  Forum: http://www.jose.it-berater.org/smfforum/index.php

                  Comment


                  • #10
                    Many, many customers spend a good amount of time converting PowerBASIC/DOS programs to one of the PowerBASIC Windows compilers. TurboBasic, QB, and others, too.

                    Any reference to INP and OUT in these programs is clearly an error in the context of a Windows program. We decided to reserve these words to assist in the conversion process. As a reserved word, they will cause an error to be generated, rather than giving the appearance of a variable name.

                    This has helped many in the conversion process, and hasn't caused any other serious issues. In fact, I only recall that this is the second time it's been noticed by anyone in years.

                    Best regards,

                    Bob Zale
                    PowerBASIC Inc.

                    Comment


                    • #11
                      My personal conclusion

                      Finally I sat down myself today for an hour to test the code again and again with different varnames.
                      Result:
                      Always the same as described above. So i cautiously dare to conclude that there might be a bug inside the variant bag, a bagbug.
                      Norbert Doerre

                      Comment


                      • #12
                        Norbert, Is this what you are trying to do?

                        Code:
                        #COMPILE EXE
                        #DIM ALL
                        #INCLUDE "WIN32API.INC"
                        
                        %DEBUGMODE = 1 
                        
                        #IF %DEF(%DEBUGMODE)
                        	GLOBAL ConHNDL AS DWORD
                        #ENDIF
                        DECLARE SUB Debug_Init()
                        DECLARE SUB DP(BYVAL variant) 
                        DECLARE SUB Debug_Terminate()
                        SUB Debug_Init()
                        	#IF %DEF(%DEBUGMODE)
                        		AllocConsole
                        		ConHNDL = GetStdHandle(%STD_OUTPUT_HANDLE)
                        	#ENDIF
                        END SUB
                        SUB DP(BYVAL xInp AS variant)
                        	#IF %DEF(%DEBUGMODE)
                        		LOCAL szBuf AS ASCIIZ * 1024, n AS LONG 
                        		IF VARIANTVT(xInp) = 8 THEN
                        		   szBuf = VARIANT$(xInp)
                        		ELSE
                        		   szBuf = STR$(VARIANT#(xInp)) & $CRLF
                        		END IF
                        		WriteConsole ConHNDL, szBuf, LEN(szBuf), VARPTR(n), %NULL
                        	#ENDIF
                        END SUB
                        SUB Debug_Terminate()
                        	#IF %DEF(%DEBUGMODE)
                        		FreeConsole
                        	#ENDIF
                        END SUB
                        
                        FUNCTION PBMAIN
                           LOCAL hDlg, x AS LONG
                           Debug_Init
                           x = 101
                           DP x
                           DIALOG NEW 0, "Test",,, 0, 0 TO hDlg
                           DIALOG SHOW STATE hDlg, %SW_HIDE
                           DIALOG SHOW MODAL hDlg
                           Debug_Terminate
                        END FUNCTION

                        Comment


                        • #13
                          Charles, that's it! Its running!

                          Charles, that's it!

                          I tried a lot of alternatives with the declaration syntax, but never found one like You propose:
                          "Declare Sub DBG(ByVal variant)"

                          Normally, I would use:
                          Declare Sub DBG(ByVal xInp As variant) ,
                          and in fact, You also use it this way in the Sub itself. I'm not shure why this syntax is running, but it could have to do something with the variant 'layout' inside the compiler.
                          It would be interesting for other users, too, to learn more about this matter to be able to understand it. Please have the kindness to tell the background.

                          History:
                          I use to program only DLLs with relatively large source code and a very small result of compiled code. For this purpose, the PB compiler IS still the best I could find, besides assembler. Nearly all my DLLs are event driven primary by an EXE, but also amongst each other. A common windows debugger does not work the way I like it. Remote debugging on the other side is depending from running two machines needing all my attention, and does not offer much comfort.
                          So, I always programmed more or less theoretically and mostly tested my skill by result. However, some of the source codes contain large and, complicated matrix math operations, and I used either 'msgbox' or my built in debug code, both limited by string input and additional 'str$(...) & str$(...) ... extra punishing code input. So, it tried at the end using variants but failed with simply a faulty declaration I still cannot explain.

                          It's running!
                          Norbert Doerre

                          Comment


                          • #14
                            Here, for completion, the code as .inc file

                            Code:
                            '----------------------------------------------------
                            'DLL-Debug Include File
                            
                            'Usage in Dll code:
                            '==================
                            
                            '%DEBUGMODE=1 'im Header der .bas-Datei
                            '#INCLUDE "..\DebugDll.inc"
                            
                            ' Debug_Init
                            ' DGB (a variant argument input)
                            ' Debug_Terminate
                            '----------------------------------------------------
                             
                            #If Not %Def(%WINAPI)
                                Declare Function WriteConsole Lib "KERNEL32.DLL" Alias "WriteConsoleA" (ByVal hConsoleOutput As Dword, lpBuffer As Asciiz, ByVal nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, ByVal lpReserved As Long) As Long
                                Declare Function GetStdHandle Lib "KERNEL32.DLL" Alias "GetStdHandle" (ByVal nStdHandle As Dword) As Dword
                                Declare Function AllocConsole Lib "KERNEL32.DLL" Alias "AllocConsole" () As Long
                                Declare Function FreeConsole Lib "KERNEL32.DLL" Alias "FreeConsole" () As Long
                            #EndIf
                            
                            #If %Def(%DEBUGMODE)
                            	Global ConHNDL As Dword
                            #EndIf
                            
                            Declare Sub Debug_Init()
                            Declare Sub DBG(ByVal variant) 
                            Declare Sub Debug_Terminate()
                            
                            Sub Debug_Init()
                            	#If %Def(%DEBUGMODE)
                            		AllocConsole
                            		ConHNDL = GetStdHandle(%STD_OUTPUT_HANDLE)
                            	#EndIf
                            End Sub
                            
                            Sub DBG(ByVal xInp As variant)
                            	#If %Def(%DEBUGMODE)
                            		Local szBuf As Asciiz * 1024
                            		Local n As Long 
                            		If VariantVT(xInp) = 8 Then
                            		   szBuf = Variant$(xInp)
                            		Else
                            		   szBuf = Str$(Variant#(xInp)) & $CrLf
                            		End If
                            		WriteConsole ConHNDL, szBuf, Len(szBuf), VarPtr(n), %Null
                            	#EndIf
                            End Sub
                            
                            Sub Debug_Terminate()
                            	#If %Def(%DEBUGMODE)
                            		FreeConsole
                            	#EndIf
                            End Sub
                            Norbert Doerre

                            Comment


                            • #15
                              Norbert, DECLARE statements only require the parameter types, whereas SUB and FUNCTIONS require the parameters and types.

                              Your "Declare Sub DBG(ByVal xInp As variant)" would be ok as well. See the PowerBasic documentation for DECLARE.

                              For what it's worth, I use something similar to what you're developing...

                              Code:
                              'include file for adding debug messages ---------------------------------------------
                              'original code by Gary Peek (05/14/2004)
                              'modified by Heber Jorge da Silva & Charles Dietz
                              'http://www.powerbasic.com/support/forums/Forum7/HTML/002320.html
                              '
                              'Name this file "debug.inc" (I keep it in my WinAPI folder)
                              'To use, just include "debug.inc"
                              'and add debug statements where ever needed:
                              '
                              '   debug v1 [, v2, ... , v6]
                              '
                              '   first debug statement creates the debug window
                              '   where vn can be any string type, integer type, or float type
                              '   set v1 = "cls"  --> clear dialog box
                              '          = "file" --> begin writing to a new file named "debug.txt"
                              '            ('clear' and 'To File' also from system menu)
                              '
                              'The specified debug items are posted to a resizable dialog box
                              'and optionally written to a file named "debug.txt"
                              '------------------------------------------------------------------------------------
                              DECLARE FUNCTION GetSystemMenu LIB "USER32.DLL" ALIAS "GetSystemMenu" (BYVAL hWnd AS DWORD, BYVAL bRevert AS LONG) AS LONG
                              DECLARE FUNCTION AppendMenu LIB "USER32.DLL" ALIAS "AppendMenuA" (BYVAL hMenu AS DWORD, BYVAL uFlags AS DWORD, BYVAL uIDNewItem AS DWORD, lpNewItem AS ASCIIZ) AS LONG
                              DECLARE FUNCTION DrawMenuBar LIB "USER32.DLL" ALIAS "DrawMenuBar" (BYVAL hWnd AS DWORD) AS LONG
                              DECLARE FUNCTION GetSystemMetrics LIB "USER32.DLL" ALIAS "GetSystemMetrics" (BYVAL nIndex AS LONG) AS LONG
                              DECLARE FUNCTION GetActiveWindow LIB "USER32.DLL" ALIAS "GetActiveWindow" () AS LONG
                              DECLARE FUNCTION SetActiveWindow LIB "USER32.DLL" ALIAS "SetActiveWindow" (BYVAL hWnd AS DWORD) AS LONG
                              DECLARE FUNCTION InsertMenu LIB "USER32.DLL" ALIAS "InsertMenuA" (BYVAL hMenu AS DWORD, BYVAL dwPosition AS DWORD, BYVAL dwFlags AS DWORD, BYVAL dwIDNewItem AS DWORD, lpNewItem AS ASCIIZ) AS LONG
                              DECLARE FUNCTION RemoveMenu LIB "USER32.DLL" ALIAS "RemoveMenu" (BYVAL hMenu AS DWORD, BYVAL nPosition AS LONG, BYVAL wFlags AS DWORD) AS LONG
                              DECLARE FUNCTION WindowMessage LIB "WINMSG.DLL" ALIAS "WindowMessageA" (BYVAL MsgNum AS LONG) AS STRING
                              
                              %MF_SEPARATOR          = &H800
                              %MF_STRING             = &H0
                              %SM_CXSCREEN           = &H0
                              %SM_CYSCREEN           = &H1
                              %WS_SYSMENU            = &H00080000
                              %WS_THICKFRAME         = &H00040000
                              %WS_VSCROLL            = &H00200000
                              %LBS_NOSEL             = &H00004000
                              %WM_USER               = &H400
                              %WM_SIZE               = &H5
                              %WM_SYSCOMMAND         = &H112
                              %MF_BYPOSITION         = &H400
                              #IF NOT %DEF(%SC_CLOSE)
                                 %SC_CLOSE = &HF060&
                              #ENDIF
                              
                              %ID_Debug = %WM_USER + 1
                              GLOBAL hDebugDlg AS LONG
                              GLOBAL hDebugCalled AS LONG
                              GLOBAL hDebugMenu AS LONG
                              GLOBAL debugCount AS LONG
                              GLOBAL debugFile AS STRING
                              DECLARE SUB debug(OPTIONAL BYVAL v1 AS VARIANT, _
                                                OPTIONAL BYVAL v2 AS VARIANT, _
                                                OPTIONAL BYVAL v3 AS VARIANT, _
                                                OPTIONAL BYVAL v4 AS VARIANT, _
                                                OPTIONAL BYVAL v5 AS VARIANT, _
                                                OPTIONAL BYVAL v6 AS VARIANT)
                              
                              SUB addDebug()
                                 ' Create dialog box for debugging info
                                 LOCAL nStyle AS LONG, wi AS LONG, ht AS LONG, x AS LONG, y AS LONG, i AS LONG
                                 hDebugCalled = GetActiveWindow 
                                 wi = CLNG(GetSystemMetrics(%SM_CXSCREEN) \ 4)   'make dlg 1/4 screen width
                                 ht = CLNG(GetSystemMetrics(%SM_CYSCREEN) \ 6)   'and 1/6 screen height
                                 nStyle = %WS_SYSMENU OR %WS_THICKFRAME
                                 DIALOG NEW 0, "Debug Info", 0, 0, wi, ht, nStyle TO hDebugDlg
                                 DIALOG PIXELS hDebugDlg, wi, ht TO UNITS wi, ht
                                 DIALOG SET SIZE hDebugDlg, wi, ht
                                 DIALOG GET CLIENT hDebugDlg TO x, y
                                 nStyle = %WS_VSCROLL OR %LBS_NOSEL
                                 CONTROL ADD LISTBOX, hDebugDlg, %ID_Debug, , 0, 0, x, y, nStyle
                                 hDebugMenu = GetSystemMenu(hDebugDlg, 0)
                                 InsertMenu hDebugMenu, 5, %MF_BYPOSITION OR %MF_SEPARATOR, -1, "-"
                                 InsertMenu hDebugMenu, 6, %MF_BYPOSITION OR %MF_STRING, %ID_Debug + 1, "&Clear "
                                 InsertMenu hDebugMenu, 7, %MF_BYPOSITION OR %MF_STRING, %ID_Debug + 2, "&To File "
                                 RemoveMenu hDebugMenu, 4, %MF_BYPOSITION
                                 RemoveMenu hDebugMenu, 3, %MF_BYPOSITION
                                 RemoveMenu hDebugMenu, 0, %MF_BYPOSITION
                                 DrawMenuBar hDebugDlg
                                 DIALOG SHOW MODELESS hDebugDlg, CALL addDebugProc
                              END SUB
                              
                              CALLBACK FUNCTION addDebugProc()
                                 LOCAL i AS LONG, x AS LONG, y AS LONG, fileNo AS LONG, msg AS STRING
                                 SELECT CASE CBMSG
                                 CASE %WM_SIZE
                                    DIALOG GET CLIENT CBHNDL TO x, y
                                    CONTROL SET SIZE CBHNDL, %ID_Debug, x, y
                                    SetActiveWindow hDebugCalled
                                 CASE %WM_SYSCOMMAND
                                    IF CBWPARAM = %SC_CLOSE THEN
                                       hDebugDlg = 0: debugCount = 0
                                    ELSEIF CBWPARAM = %ID_Debug + 1 THEN
                                       LISTBOX RESET hDebugDlg, %ID_Debug: debugCount = 0
                                    ELSEIF CBWPARAM = %ID_Debug + 2 THEN
                                       debugFile = "debug.txt": KILL debugFile
                                       OPEN debugFile FOR OUTPUT AS fileNo
                                       FOR i = 1 TO debugCount
                                          LISTBOX SELECT CBHNDL, %ID_Debug, i
                                          LISTBOX GET TEXT CBHNDL, %ID_Debug TO msg 
                                          PRINT #fileNo, msg
                                       NEXT i   
                                       CLOSE #fileNo
                                    END IF
                                 END SELECT
                              END FUNCTION
                              
                              SUB debug(OPTIONAL BYVAL v1 AS VARIANT, _
                                        OPTIONAL BYVAL v2 AS VARIANT, _
                                        OPTIONAL BYVAL v3 AS VARIANT, _
                                        OPTIONAL BYVAL v4 AS VARIANT, _
                                        OPTIONAL BYVAL v5 AS VARIANT, _
                                        OPTIONAL BYVAL v6 AS VARIANT)
                                 LOCAL Msg AS STRING, i AS LONG, n AS LONG
                                 STATIC fileNo AS LONG
                                 DIM v(6) AS VARIANT
                                 IF hDebugDlg = 0 THEN addDebug
                                 v(1) = v1 : v(2) = v2 : v(3) = v3 : v(4) = v4 : v(5) = v5 : v(6) = v6
                                 FOR i = 1 TO 6
                                    n = VARIANTVT(v(i))
                                    IF n = 8 THEN
                                       IF i = 1 AND UCASE$(VARIANT$(v(i))) = "CLS" THEN 'clear window
                                          LISTBOX RESET hDebugDlg, %ID_Debug: msg = "": debugCount = 0
                                       ELSEIF i = 1 AND UCASE$(VARIANT$(v(i))) = "FILE" THEN 'write to debug file
                                          debugFile = "debug.txt": KILL debugFile: msg = ""
                                       ELSE
                                          msg = msg + VARIANT$(v(i)) + ", "
                                       END IF
                                    ELSEIF n <> 0 THEN
                                       msg = msg + STR$(VARIANT#(v(i))) + ", "
                                    END IF
                                 NEXT
                                 msg = RTRIM$(msg, ANY ", ")
                                 IF LEN(msg) = 0 THEN EXIT SUB
                                 IF LEN(debugFile) THEN
                                    OPEN debugFile FOR APPEND AS fileNo
                                    PRINT #fileNo, msg: CLOSE #fileNo
                                 END IF
                                 LISTBOX ADD hDebugDlg, %ID_Debug, msg: INCR debugCount
                                 LISTBOX SELECT hDebugDlg, %ID_Debug, debugCount
                              END SUB
                              Last edited by Charles Dietz; 7 Mar 2008, 10:05 AM.

                              Comment


                              • #16
                                FWIW the only debug tool I use now is TRACE!!

                                Handles everything my programs need

                                James

                                Comment


                                • #17
                                  >FWIW the only debug tool I use now is TRACE!!

                                  .. and the best "performance tuning" tool is PROFILE!!

                                  Amazing how few users it seems are aware of these tools.
                                  Michael Mattias
                                  Tal Systems (retired)
                                  Port Washington WI USA
                                  [email protected]
                                  http://www.talsystems.com

                                  Comment


                                  • #18
                                    Very good debug code with sys menu

                                    Charles, the latest code You sent is really what I always have desired. It is the one I always dreamt from while in struggle with debugging my code manually. But I never took the time to write it, knowing that it might also take a day or more, and because I always thought of doing it "next time". ;-<

                                    So I'm quite happy now to see that several authors - including You - were engaged in the same problem before.
                                    Norbert Doerre

                                    Comment

                                    Working...
                                    X