Announcement

Collapse
No announcement yet.

PB DLL wants dynamic string BYVAL

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

    PB DLL wants dynamic string BYVAL

    A 3rd-party SQLitening.dll written in PB wants strings BYVAL.
    Is there a way to pass dynamic string from VB6 (which converts BYVAL to ASCIIZ?)
    I can write another DLL and accept the strings as ASCIIZ and then pass
    them onto the 3rd-party DLL BYVAL, but thought there might be a better way.

    It looks like a PB DLL will accept a BYVAL string from VB6, but getting unpredictable results.


    VB Code:
    Code:
    Private Sub Command1_Click()
      Dim sIp As String
      Dim PortNumber As Long
      Dim rsModChars As String
      Dim result As Long
      PortNumber = 51234
      rsModChars = "E0"
      sIp = "192.168.0.101"
      rsModChars = "E0"
      result = slConnect(ByVal sIp, ByVal PortNumber, ByVal rsModChars)  'call 3rd party PB DLL.
    This seems to work:
    VB6 calls mConnect that calls the 3rd party DLL function slConnect.

    Code:
    FUNCTION mConnect(rsServer AS ASCIIZ, BYVAL PortNumber AS LONG, rsModChars AS ASCIIZ) EXPORT AS LONG
      LOCAL result AS LONG
      ? rsServer
      slSetProcessMods "E0"
      result = slConnect(BYVAL rsServer, BYVAL PortNumber, BYVAL rsModChars)
      MSGBOX STR$(result)
    END FUNCTION
    Last edited by Mike Doty; 20 Oct 2008, 07:56 PM.

    #2
    A 3rd-party SQLitening.dll written in PB wants strings BYVAL.
    Is there a way to pass dynamic string from VB6 (which converts BYVAL to ASCIIZ?)
    I'm not a VB guy but I seem to recall reading here that VB keeps "DIM S AS STRING" variables as an OLE string, but in Unicode?

    If so there should be a way to convert to ANSI (MultiByteToWideChar or WideCharToMultiByte), overwriting another VB "AS STRING" variable, then passing BYVALUE the integer at VARPTR(the second string).

    (Whomever designed this API wasn't thinking about VB users I guess. Why that library does not want "AS ASCIIZ" is kind of a mystery to me.)

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

    Comment


      #3
      As one that came from VB and did not really understand the difference between Asciiz and String (and would like to correct that train of thought) would that mean all my exported functions that accept strings, should be changed to Asciiz for compatibility with other programming languages?

      Strings were originally used due to the unknown length of the string at runtime, but could be changed to Asciiz * (Some large value larger than any possible string passed)
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


        #4
        AFAIK, VB does not support PowerBASIC's BYVAL STRING parameters. It can be made to support BYREF STRING using internal conversion, buit that's about it with dynamic strings.
        kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

        Comment


          #5
          Originally posted by Cliff Nichols View Post
          Asciiz for compatibility with other programming languages?
          more often than not it is a string pointer which is passed, then all you have to know is whether the recipient is expecting it to be a dynamic string or zero-terminated. Lots of API functions take a length parameter which can be defaulted for a zero-terminated string. Look out for length if you are passing UNICODE strings, as each UNICODE character occupies two bytes.

          Comment


            #6
            Actually Michael if you read Mikes conversion code you will see that he is passing the third party an ASCIIZ string that is not Mikes problem, the problem is it wants the string BYVAL. As you said VB stores strings in Unicode and if you pass a string BYVAL it carries out a "fudge", converting the string to an ASCIIZ which it then passes BYREF. This was done to allow VB to use the API which being written in C normally expects that or a pointer to a buffer and a length.
            Mike not sure if it will work but I think you can create a fixed length sting in VB longer than needed (easy in this case as max length of an IP addess is 15) then build the fixed length string up one character at a time with ChrB(Asc("each character")) and adding ChrB(0) after the last character and then pass the fixed length BYVAL

            Comment


              #7
              PB "BYVAL AS STRING" wants a 32-bit integer = OLE string handle.

              The build char-by-char thing could be the ticket here....

              MCMs VB code not having used VB for at least ten years
              Code:
               DECLARE THE FUNCTION ([B]BYVAL AS LONG[/B] instead of string, rest of params) 
              
               DIM S AS STRING 
               S   = SPACE$( ANSI len + 1) 
               dest =  STRPTR(S)            ' point to the stringdata 
               Addr =  VARPTR(S)           ' address of handle 
               Handle =  CVL(PEEK$(Addr, 4)) ' convert what is at address to an integer 
              
               FOR Z = 1 TO LEN_OF_DATA 
                  POKE  dest, ASC(MID$(Source, Z,1) )  ' poke a byte 
                  Dest = dest + 1 
               NEXT 
               Poke dest, 0  ' terminate the OLE string 
               CALL Thefunction (Handle) ' pass handle ByValue.
              I think that might be close.

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

              Comment


                #8
                Michael
                Read Mikes mConnect function which works, it receives an ASCIIZ string BYREF and then passes an ASCIIZ string BYVAL, no other conversion.
                The thread could have had a better title so I suspect passing a 32 bit pointer to an OLE string will gaurentee a GPF.
                John

                Comment


                  #9
                  How about those threads saying need help. I usually skip them.

                  Thanks for the help and suggestions. I will try suggestions above and
                  try the VB buillt-in string functions and a byte array. There is probably
                  something in VB6 that can be used to eliminate the extra DLL.
                  The extra DLL has turned out to be a big advantage because it gives
                  all the features of PB to the VB program like sorting and keeping the
                  data in ascii. My solution may work, but the VB people using
                  SQLitening are going to have GPF's and this might be more for them over
                  at Paul's site.

                  Comment


                    #10
                    Mike
                    Lets know what you come up with, is an interesting problem. though would be careful with MCM's example as I don't think VB knows how to use PB instructions like PEEK and POKE
                    John

                    Comment


                      #11
                      I've been reading this.
                      Learn the performance of VB6 String functions. Learn to call the Unicode API functions and to build really, really huge strings.

                      Comment


                        #12
                        Hi Mike,

                        SQLitening was written with native PowerBASIC users in mind because the code Fred is using is based on code he has used in PB for a long time. I doubt that he envisioned it being used by other languages. That's why the code uses BYVAL AS STRING when declaring string parameters.

                        I guess the easiest solution is revise the PowerBASIC parameters to be BYREF AS ASCIIZ. That way you could use BYVAL STRING in your VB program and interface directly with the DLL. However, this also means that it becomes a little more cumbersome for PB user because they now need to pass a dynamic string to the DLL using BYCOPY rather than directly like previously. String literals and ASCIIZ strings would be okay - just string variables declared AS STRING would need to be passed BYCOPY.

                        Fred is away on holidays for another week or so. We could go ahead and make the change but it would be nice to get his opinion first because this will be a major change in the DLL's operation and will affect many functions in the DLL.
                        Paul Squires
                        FireFly Visual Designer (for PowerBASIC Windows 10+)
                        Version 3 now available.
                        http://www.planetsquires.com

                        Comment


                          #13
                          Fred is away on holidays for another week or so. We could go ahead and make the change but it would be nice to get his opinion first because this will be a major change in the DLL's operation and will affect many functions in the DLL.
                          Why not just add and EXPORT an additional "zConnect" function, which does nothing more than internally call the current function after converting the ASCIIZ [in] to the BYVAL STRING required?

                          (I do this in my 837 API... you can call with OLE strings or NTS strings simply by calling a different EXPORTed function).

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

                          Comment


                            #14
                            Michael
                            Apologies, seems Mike left out a rather important line in his example code ie the DECLARE statement which caused PB to do an automatic conversion of an ASCIIZ string to an OLE string.
                            Paul
                            The same applies for PB. If the DLL uses BYREF (implied or otherwise) as ASCIIZ and the DECLARE in the calling PB program is the same as VB then PB will automatically convert a defined OLE string to ASCIIZ before passing it to the sub or function. Freds code then becomes simply multi-language. I have been doing it that way since 16 Bit VB with 16 Bit PB.
                            John
                            Last edited by John Petty; 21 Oct 2008, 01:11 PM.

                            Comment


                              #15
                              Hi Michael,

                              Yes, that's the approach I used with the Cheetah Database DLL that I wrote. I ended up having two different types of functions. One regular function and another "z" type of function that fed the regular function after converting. We may end up going that route again.
                              Paul Squires
                              FireFly Visual Designer (for PowerBASIC Windows 10+)
                              Version 3 now available.
                              http://www.planetsquires.com

                              Comment


                                #16
                                Paul
                                Not sure my descriptions make it clear so here is a simple PB exe and DLL to illustrate
                                Code:
                                #COMPILE EXE
                                #DIM ALL
                                DECLARE SUB test LIB "test.dll" ALIAS "TEST" (BYVAL t AS STRING)
                                
                                FUNCTION PBMAIN () AS LONG
                                   LOCAL s AS STRING
                                   s = "DEF"
                                   test s
                                END FUNCTION
                                
                                'code for test.dll
                                #COMPILE DLL
                                #DIM ALL
                                SUB test(t AS ASCIIZ) EXPORT
                                    ? t
                                END SUB

                                Comment


                                  #17
                                  Hi John,

                                  That's pretty cool - I just tried a quick test and sure enough it works exactly like you explain. I guess the only "downside" is that PB users would then be subject to a string conversion performance hit. Maybe someone can confirm that PB does indeed create an ASCIIZ string from the dynamic string, or does it just pass a pointer to the OLE string knowing that the OLE string is null terminated anyway? Sounds like a questions for the guys over at support maybe.
                                  Paul Squires
                                  FireFly Visual Designer (for PowerBASIC Windows 10+)
                                  Version 3 now available.
                                  http://www.planetsquires.com

                                  Comment


                                    #18
                                    My test was almost exactly like yours.

                                    Code:
                                    #Compile Exe
                                    
                                    Declare Function mysub Lib "testdll.dll" Alias "MYSUB"( ByVal zStr As String ) As Long
                                    
                                    
                                    
                                    Function PBMain() As Long
                                    
                                       Local s As String
                                       
                                       s = "paul squires"
                                       
                                       mysub s
                                       
                                    
                                    End Function
                                    
                                    
                                    
                                    #Compile Dll
                                    
                                    Function mysub( ByRef zStr As Asciiz ) Export As Long
                                    
                                       ? zStr
                                       
                                    End Function
                                    Paul Squires
                                    FireFly Visual Designer (for PowerBASIC Windows 10+)
                                    Version 3 now available.
                                    http://www.planetsquires.com

                                    Comment


                                      #19
                                      Um, excuse me guys, but those tests prove only what is well-known: the PB compiler will do an awful lot of converting without being asked. It does numbers, expressions, literals and all kinds of stuff... the stuff which has made BASIC a popular and long-lived programming language.

                                      Think about it... have you ever used an expression for a parameter? How about a string or numeric literal? In these cases the compiler is handling the conversion of that expression result or literal to the datatype required by the called function, regardless if that function is internal or external.

                                      The real problem here was that the function in question was designed to accept a "BYVAL AS [OLE] STRING" parameter...a calling convention which is simply NOT very "Microsoft Visual Basic-Friendly."

                                      If you have the luxury of being the function designer, "address of data and valid length" OR "address of null-terminated string" are vastly superior ways to specify string parameters - a calling convention which will be easy-to-use and familiar regardless of calling environment.


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

                                      Comment


                                        #20
                                        Originally posted by Michael Mattias View Post
                                        Um, excuse me guys, but those tests prove only what is well-known: the PB compiler will do an awful lot of converting without being asked. MCM
                                        Gee if it is so well known what was this all about
                                        Why not just add and EXPORT an additional "zConnect" function, which does nothing more than internally call the current function after converting the ASCIIZ [in] to the BYVAL STRING required?
                                        Paul
                                        Have had some quick looks at the registers etc in debug mode and don't know the answer though would guess as its PB the performance hit is minimal.
                                        Have to be honest and say I didn't know there was any other to do it. 14 or so years ago writing 16 Bit Dlls using PB 1.1 for VB 3 that was how it was done. Sometime later (forget when) but before DDT as I don't have a clue about SDK I realised I could write quick EXE's in PB that didn't require windows (still do) just copied and pasted my declares from VB with minor modifications and everything worked. Pure accident, have numerous DLLs including my own data base engine thats been improved over 25 years (but even the latest version can still read originals written in GW Basic) that I regularly call from both PB and VB.
                                        Thats why I keep buying PB.
                                        John

                                        Comment

                                        Working...
                                        X
                                        😀
                                        🥰
                                        🤢
                                        😎
                                        😡
                                        👍
                                        👎