Announcement

Collapse
No announcement yet.

Question to chunk UDT conversion from C++

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

  • Question to chunk UDT conversion from C++

    From one of my older C++ codes i have to translate an UDT with PB 9.
    I'm not lucky with my own solution because it seems to be combined with some perhaps unnecessary circumstances in syntax.

    ###################### C++ #######################

    //C++ UDT:
    Code:
    typedef struct uidIndex{
    	long erased;
    	long handle;
    	unsigned long uid;
    }idx;
    //In my old C++ Library i wrote a bunch of functions to get the size and content of Chunk Data inside a drawing header. The two lines below are the essential ones. As you can see in the C++ syntax, the UDT 'idx' is char* defined. It seems that in PB i can only use an UDT pointer.

    short iSize = GetCurrentEntityChunkSize(&iError, iIndex);
    GetCurrentEntityChunk(&iErr, i, (char*)&idx);


    Has´anyone an idea how to do it like with C++?

    '###################### PB9 #######################

    'PB9 UDT
    Code:
    Type IMG_UDATA
    	Erased As Long
    	EntH As Long
       UID As Long
    End Type
    Global IDX As IMG_UDATA
    
    iSize = GetCurrentEntityChunkSize(iErr, iIndex) 
    GetCurrentEntityUDChunk(iError, iIndex, p) 'p = pointer to UDT

    '############## PB9 functioning Sample ###############
    Code:
    Function StoreHandleByUIDImage(UID As Long, EntH As Long, tfAdd As Integer) As Long
       'Writes handle 'EntH' of ímage frame to drawing header, 
       'if current unique identifier UID of the image frame is the same as the one in drawing header.
       'INPUT: UID = UID of Img Frame, tfADD: 0=erase, 1=update
       'OUTPUT: m_Changed = frame changed
       'Function value: 0=error, 1=success
    	Local iError As Integer
    	Local iSize As Integer
    	Local iUDCount As Integer
    	Local iIndex As Integer
    	Dim ud As IMG_UDATA
    	Dim p As IMG_UDATA Pointer
    	p = VarPtr(ud)   
    	Function = 0
    	m_Changed = 0
    	If EntH > GetLastKnownImage() Then SetLastKnown(EntH)
    	SetHeaderData(iError)
    	SetDataName(iError, "mcimage")
    	iUDCount = GetCurrentEntityUDCount(iError)
    	For iIndex = 1 To iUDCount
    	   iSize = GetCurrentEntityChunkSize(iError, iIndex)
    		GetCurrentEntityUDChunk(iError, iIndex, p)
    		If @p.UID = UID Then
    		   @p.Erased = @p.EntH  'EntH = handle of erased image			
                                @p.EntH = EntH
    			SetCurrentEntityUDChunk(iError, i, p, SizeOf(p))
    			Function = 1
    			Exit Function
    		End If
    	Next iIndex
    	If tfAdd = 1 Then 'add to database
    		@p.UID = UID
    		@p.Erased = -1 ' -1 = don't erase
    		@p.EntH = EntH
    		AddCurrentEntityUDChunk(iError, p, SizeOf(p))
    		m_Changed = 1 '(globaly definided)
    	End If
    End Function
    Last edited by norbert doerre; 21 Mar 2010, 04:47 PM.
    Norbert Doerre

  • #2
    It all depends onn how you declare the procedure (not shown).

    If you declare it as:

    Code:
    DECLARE SUB GetCurrentEntityChunk(BYREF iErr AS INTEGER, BYVAL i AS INTEGER, BYREF idx AS IMG_UDATA)
    then you can call it as:

    Code:
    DIM ud As IMG_UDATA
    GetCurrentEntityUDChunk(iError, iIndex, ud)
    If ud.UID = UID Then
    ...
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      Solution: Question to chunk UDT conversion from C++

      José, here my solution with your hint:
      The size of the code has decreased considerably for my happyness!

      Type IMG_UDATA
      ErasH As Long
      EntH As Long
      UID As Long
      End Type

      I added a new SUB "RetrieveImageHeaderUdata" to my library using the present SUB:

      Present SUB:
      Declare Sub GetCurrentEntityChunk Lib "MCUDATA.DLL" Alias "GetCurrentEntityChunk" (iError As Integer, ByVal iIndex As Integer, ByVal p As Dword)

      New SUB:
      Declare Sub RetrieveImageHeaderUdata Lib "MCUdata.DLL" Alias "GetCurrentEntityChunk" (ByRef iError As Integer, ByVal iIndex As Integer, ByRef idx As IMG_UDATA)

      '-------------------------------------------------------------------------
      ' Sub RetrieveImageHeaderUdata()
      '-------------------------------------------------------------------------
      Code:
      Sub RetrieveImageHeaderUdata(iUDIndex As Long, UDImage As IMG_UDATA)
         'Get UDT with Image-UserData
         'INPUT: iUDIndex = Index of Image-UserData in Drawing-Header
         'OUTPUT: Image-UserData as UDT with Elements "ErasH", "EntH" and "UID"
         Local iErr as integer
         Local iChunkSize As Integer
         Dim UD As IMG_UDATA
         GetCurrentEntityImageUserData(iErr, iUDIndex, UD)
         UDImage.ErasH = UD.ErasH
         UDImage.EntH = UD.EntH
         UDImage.UID = UD.UID
      End Sub
      Last edited by norbert doerre; 22 Mar 2010, 09:02 AM.
      Norbert Doerre

      Comment


      • #4
        //C++ UDT:
        Code:
        typedef struct uidIndex{
        	long erased;
        	long handle;
        	unsigned long uid;
        }idx;
        'PB9 UDT
        Code:
        [B]Type IMG_UDATA
        	Erased As Long
        	EntH As Long
           UID As Long
        End Type
        The UID As Long should actually be UID As DWORD since the C++ struct has it defined as unsigned long. This is probably not a big deal in this situation, but in others it will cause a negative number to be shown when a positive value is expected.
        Scott Slater
        Summit Computer Networks, Inc.
        www.summitcn.com

        Comment


        • #5
          Updating old code by first redeclaring all functions

          Scott,
          yes, it should be in fact a dword. As you can see from the declaration called 'present' before in this thread, I already corrected all function declarations from long to dword, where necessary, and there are several hundreds of them.
          I declare each of my functions still explicitely in the old style to beware controllable compatibility. As soon as a new coded function contains a negative long value where a dword is necessary, executing this function currently runs into an error.
          But i have still to update a big part of my dll code. Please consider that it's roots date from the early 80s and have been "tested" until today with Fortran, C, C++ and all PB versions. So it is a good study for me to compare it with the needs of today.
          Norbert Doerre

          Comment


          • #6
            You can still shorten it using:

            Code:
            TYPE SET UDIMage = UD
            instead of:

            Code:
            UDImage.ErasH = UD.ErasH
            UDImage.EntH = UD.EntH
            UDImage.UID = UD.UID
            Or even get rid of UD and fill UDImage directly:

            Code:
            GetCurrentEntityImageUserData(iErr, iUDIndex, UDImage)
            Forum: http://www.jose.it-berater.org/smfforum/index.php

            Comment


            • #7
              Variable separation to distinguish inner and outer values

              José, i learnt 35 years ago to separate a function's outer and inner variables with a buffer variable as soon as they are used in both directions. May be this is obsolete nowadays, but it gives me a better control over my DLLs while debugging. They generally don't function when they are compiled as an ÉXE because their functions must be invokable interactively. I use here a built in debugging function as an include file working with variables only. With variable separation i can better distinguish between incoming and outgoing values.
              Norbert Doerre

              Comment

              Working...
              X