Announcement

Collapse
No announcement yet.

C# and PB string

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

  • C# and PB string

    I want to use one PB/WIN DLL exporting a function AS STRING
    altogether with C#.

    Do you know how to retrieve it from C#
    when you have no idea of the PB's string LENGTH ?

    I have seen this link http://www.powerbasic.com/files/pub/...NetString2.zip
    however it does use a known string length.



    ------------------
    Patrice Terrier
    mailto[email protected][email protected]</A>
    www.zapsolution.com
    Addons: WinLIFT (Skin Engine), GDImage (Graphic control), Artwork (logo creation), GDI+ Helper (GDIPLUS)
    Patrice Terrier
    www.zapsolution.com
    www.objreader.com
    Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

  • #2
    Patrice,

    if you use PB dynamic strings it is quite easy to get the len.
    Once you have the STRPTR to the dynamic string, just move back
    4 bytes and you will get the len of the PB string as a DWORD.

    Example:
    Code:
    DIM MyStr AS STRING
    DIM sLen  AS DWORD
    
    MyStr = "ABCDEF"
    
    sLen = PEEK(DWORD, STRPTR(MyStr) - 4)
    So, if you have the STRPTR in your C# code, you can get the len.

    I didn't read you ZIP file, so sorry if this is not what you was searching for.

    Eros


    ------------------
    thinBasic from Eros Olmi
    mailto:[email protected][email protected]</A>



    [This message has been edited by Eros Olmi (edited September 14, 2006).]
    thinBasic programming language
    Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

    Comment


    • #3
      Because all OLE strings are by definition null terminated, if you have the address of the string data you can get the length using the lstrlen WinAPI function.

      (But that needs the address of the data, not the value/address of the handle).

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

      Comment


      • #4
        I believe the language C# (C sharp) does not support using the Windows API, you have to use "marshalling" to get real memory pointers. I could be wrong though as I don't have much experience with C#.

        ------------------
        kgpsoftware.com
        Slam Database Manager - simple, but effective database system.
        PrpT Property List - kiss those complex 'options dialogs' goodbye!
        kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

        Comment


        • #5
          My problem is to retrieve in C# the string returned by this PB function
          DECLARE FUNCTION ZI_Version LIB "GDIMAGE.DLL" ALIAS "ZI_Version" () AS STRING

          ------------------
          Patrice Terrier
          mailto[email protected][email protected]</A>
          www.zapsolution.com
          Addons: WinLIFT (Skin Engine), GDImage (Graphic control), Artwork (logo creation), GDI+ Helper (GDIPLUS)
          Patrice Terrier
          www.zapsolution.com
          www.objreader.com
          Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

          Comment


          • #6
            Michael,

            I may be wrong here but you can correct me for future reference.

            An OLE string IS terminated by a NUL because of PB does it.
            An OLE string can contain NUL chars inside so lstrlen API function can fail here
            to get the whoole string len but it would get the len till the first NUL.
            But because Patrice seems getting back the ZI_Version, I assume it is in clear text form
            so lstrlen would work.

            Back to Patrice problem, when you declare a PB function returning a STRING in reality
            you will find a DWORD in the stack. That DWORD is the STRPTR pointer to the buffer
            containing the string.

            Code:
                      LOCAL pStr AS DWORD
                      LOCAL sLen AS LONG
            
            '---Imagine pStr is the returning value
            
                      IF pStr > 0 THEN
                        sLen = CVL(PEEK$(pStr-4, 4)) 
                        IF sLen > 0 THEN
                          MyString = PEEK$(pStr, sLen )
                        ELSE                       
                          MyString = ""
                        END IF
                        SysFreeString(pStr)
                      ELSE
                        MyString = ""
                      END IF
            In my interpreter I can dynamically call external PB function returning dynamic string
            but in reality I read a DWORD fcrom the stack and use the above code to get the string.

            Again I can be wrong but till now all my tests on dynamic calling is working fine.

            Mr Zale could confirm it.

            Regards
            Eros


            ------------------
            thinBasic from Eros Olmi
            mailto:[email protected][email protected]</A>

            [This message has been edited by Eros Olmi (edited September 14, 2006).]
            thinBasic programming language
            Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

            Comment


            • #7
              To demonstrate my previous sentence here it is the tests.
              A DLL exporting a function returning a STRING
              A EXE declaring the same external function but returning a DWORD.

              Try and see.

              DLL
              Code:
              #COMPILE DLL "sLenDLL.DLL"
              #DIM ALL
              
              FUNCTION MyVersion ALIAS "MyVersion" () EXPORT AS STRING
                  FUNCTION = "123456"
              END FUNCTION
              EXE
              Code:
              #COMPILE EXE
              #DIM ALL
              
              #INCLUDE "WIN32API.INC"
              
              DECLARE FUNCTION MyVersion LIB "sLenDLL.DLL" ALIAS "MyVersion" () AS DWORD
              
              FUNCTION PBMAIN () AS LONG
              
                  LOCAL pStr AS DWORD
                  LOCAL sLen AS LONG
                  DIM MyString AS STRING
                  
                  pStr = MyVersion
                  IF pStr > 0 THEN
                      sLen = CVL(PEEK$(pStr-4, 4))
                      IF sLen > 0 THEN
                          MyString = PEEK$(pStr, sLen )
                      ELSE
                          MyString = ""
                      END IF
                      SysFreeString(pStr)
                  ELSE
                      MyString = ""
                  END IF
              
                  MSGBOX MyString
              
              END FUNCTION

              ------------------
              thinBasic from Eros Olmi
              mailto:[email protected][email protected]</A>



              [This message has been edited by Eros Olmi (edited September 14, 2006).]
              thinBasic programming language
              Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

              Comment


              • #8
                And to demonstrate the NUL see this variation:

                DLL
                Code:
                #COMPILE DLL
                #DIM ALL
                
                FUNCTION MyVersion ALIAS "MyVersion" () EXPORT AS STRING
                    FUNCTION = "123" & $NUL & "456"
                END FUNCTION
                EXE
                Code:
                #COMPILE EXE
                #DIM ALL
                
                #INCLUDE "WIN32API.INC"
                
                DECLARE FUNCTION MyVersion LIB "sLenDLL.DLL" ALIAS "MyVersion" () AS DWORD
                
                FUNCTION PBMAIN () AS LONG
                
                    LOCAL pStr AS DWORD
                    LOCAL sLen AS LONG
                    DIM MyString AS STRING
                    
                    pStr = MyVersion
                    IF pStr > 0 THEN
                        sLen = CVL(PEEK$(pStr-4, 4))
                        IF sLen > 0 THEN
                            MyString = PEEK$(pStr, sLen )
                        ELSE
                            MyString = ""
                        END IF
                        SysFreeString(pStr)
                    ELSE
                        MyString = ""
                    END IF
                
                    MSGBOX "Len is:" & STR$(sLen) & " String is: " & MyString   '<<< here only 123 will be shown due to msgbox
                
                END FUNCTION

                ------------------
                thinBasic from Eros Olmi
                mailto:[email protected][email protected]</A>



                [This message has been edited by Eros Olmi (edited September 14, 2006).]
                thinBasic programming language
                Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                Comment


                • #9
                  I think the above method of reading PB strings can open a lot of possible
                  implementations of dynamic string exchange from DLL developed with PB and
                  other languages like C or in general languages not directly supporting
                  OLE strings but supporting any kind of memory handling with pointers.

                  I've used it a lot to interface and exchange string buffers with C DLLs.
                  More, it is very easy and very fast.

                  ------------------
                  thinBasic from Eros Olmi
                  mailto:[email protected][email protected]</A>

                  [This message has been edited by Eros Olmi (edited September 14, 2006).]
                  thinBasic programming language
                  Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                  Comment


                  • #10
                    >An OLE string IS terminated by a NUL because of PB does it.

                    Nope, Mr. Gates does it, and this is documented

                    > An OLE string can contain NUL chars inside so lstrlen API function can fail here
                    > to get the whoole string len but it would get the len till the first NUL.

                    True.


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

                    Comment


                    • #11
                      Right you are.

                      ------------------
                      thinBasic from Eros Olmi
                      mailto:[email protected][email protected]</A>
                      thinBasic programming language
                      Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                      Comment


                      • #12
                        My simple try.
                        http://www.codeproject.com/dotnet/strings.asp
                        http://www.developerfusion.co.uk/show/4697/
                        This a net or stringbuilder article, however, bet it applies. http://msdn.microsoft.com/library/de...Parameters.asp
                        ------------------
                        Roy Cline



                        [This message has been edited by Roy Cline (edited September 14, 2006).]
                        Roy Cline

                        Comment


                        • #13
                          this worked for me
                          I had other problems and gave up on it for now.

                          Code:
                          'PB
                          ' --------------------------------------------------
                          ' --------------------------------------------------
                          FUNCTION sqlite3tonet_errmsg ALIAS "sqlite3tonet_errmsg" ( BYVAL hDB AS LONG ) EXPORT AS STRING
                          '    LOCAL pzErr AS ASCIIZ PTR
                          '    LOCAL sErr AS STRING
                          '    pzErr = sqlite3_errmsg(hDB)
                          '    FUNCTION = @pzErr
                              FUNCTION = "I got it!!!"
                          END FUNCTION
                          ' --------------------------------------------------
                          ' --------------------------------------------------
                          '
                          VB.NET
                          '
                          ' --------------------------------------------------
                          ' --------------------------------------------------
                          Public Class SQLiteDB
                              Private m_FileSpec As String
                              Private m_hDB As Integer
                              Private m_IsOpen As Boolean
                          
                          '
                          ' declare PB DLL function in NET
                          Private Declare Ansi Function sqlite3tonet_errmsg Lib "SQLite3ToNet.dll" Alias "sqlite3tonet_errmsg" (ByVal hDB As Integer) As String
                          '
                          ' note "Ansi"
                          '
                          Public Function ErrMsg() As String
                                  If m_hDB <> 0 Then
                                      Return sqlite3tonet_errmsg(m_hDB)
                                  Else
                                      Return ""
                                  End If
                              End Function
                          End Class
                          '  --------------------------------------------------
                          ' --------------------------------------------------
                          Added: I think VB6 friendly variables will pass OK.
                          Forgot to mention these:
                          Imports System
                          Imports Microsoft.VisualBasic
                          Imports System.Runtime.InteropServices


                          This is a mono article, but it covers the topic in depth.
                          http://www.mono-project.com/Interop_...tive_Libraries

                          ------------------




                          [This message has been edited by Stan Durham (edited September 14, 2006).]

                          Comment


                          • #14
                            The C# and VB.NET syntax are not same,
                            C# is my concern.

                            I shall dig it up based on the provided informations.

                            Thank you ALL

                            ------------------
                            Patrice Terrier
                            mailto[email protected][email protected]</A>
                            www.zapsolution.com
                            Addons: WinLIFT (Skin Engine), GDImage (Graphic control), Artwork (logo creation), GDI+ Helper (GDIPLUS)
                            Patrice Terrier
                            www.zapsolution.com
                            www.objreader.com
                            Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                            Comment


                            • #15
                              Here is the C# syntax to declare a PB string function
                              and a PB long function.

                              - PB
                              DECLARE FUNCTION RegisterGLImageClass LIB "GDIMAGE.DLL" ALIAS "RegisterGLImageClass" () AS LONG

                              DECLARE FUNCTION ZI_Version LIB "GDIMAGE.DLL" ALIAS "ZI_Version" () AS STRING

                              - C#
                              [DllImport(@"c:\travail\gdimage\gdimage.dll")]
                              public static extern int RegisterGDImageClass();

                              [DllImport(@"c:\travail\gdimage\gdimage.dll")]
                              public static extern string ZI_Version();




                              ------------------
                              Patrice Terrier
                              mailto[email protected][email protected]</A>
                              www.zapsolution.com
                              Addons: WinLIFT (Skin Engine), GDImage (Graphic control), Artwork (logo creation), GDI+ Helper (GDIPLUS)
                              Patrice Terrier
                              www.zapsolution.com
                              www.objreader.com
                              Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                              Comment

                              Working...
                              X