Solved

How could i convert c soruce to Delphi ?

Posted on 2006-06-25
2
283 Views
Last Modified: 2010-04-05
Hello,

I Want to convert c source code to delphi.
c source code explain.
Out of this code call back function will fill data into Stats[] array. Then Extract the packed record data from Global Array in the For loop.

But, i do not know how can i extract Structure packed data on the Delphi code.

Please, Help me.


--- C Code ---
typedef struct {
   ULONG                seq; ( 4 BYTE )
    LARGE_INTEGER     time;
    char                text[0];
} ENTRY, *PENTRY;
      
      
PENTRY      ptr;            

DWORD StatsLen;
char  Stats[ MAX_STORE ];

------- I want to extract data from global Stats array with Delphi ---------
for ( ptr = (void *)Stats; (char *)ptr < min(Stats+StatsLen,Stats + sizeof (Stats)); )  
{
ULONG len = strlen(ptr->text);
printf("%s \n", ptr->text );      
len += 4;
len &= 0xFFFFFFFC; // +1 for null-terminator +3 for 32bit alignment
ptr = (void *)(ptr->text + len);
}


      
0
Comment
Question by:viruszone
2 Comments
 
LVL 4

Expert Comment

by:Radler
ID: 16985785
It´s  a draft

//types and vars definitions


{$R-} //C pointers requires this frequently
type
      TEntry = record
            seq : WORD;
            time : longint; //A guess to LARGE_INTEGER omitted here
            text : array[0..0] of char;
      end;

      PEntry = ^TEntry;


var
      StatsLen : DWORD;
      Stats : array[0..MAX_STORE ] of char; //MAX_STORE = ?
      //additionals
      limit, len : integer;//a integer var must be created to len end limit
      ptr : PEntry;



//------------------------------ code segment ---------------------

limit:=Math.Min(Integer(Stats)+StatsLen,Integer(Stats) + SizeOf(Stats));
ptr:=PEntry( @Stats ); //type cast necessary
while( integer(ptr) < limit ) do begin
      len = strlen(ptr->text);
      MessageDlg(ptr^.text + #13, mtInformation, [mbOK], 0); //a simple output to non console app
      Inc(len, 4); //jump the  final part of struture( this value maybe is incorrect and/or variable )
      len := len and $FFFFFFFC; // +1 for null-terminator +3 for 32bit alignment
      ptr = integer(ptr) + len;
end;


*** NOTE: turn off range checking {$R-} to avoid false range errors
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 250 total points
ID: 16986587

The fields structures for seq and time are actually ULONG(4 bytes) and LARGE_INTEGER(8 bytes), both of which are defined in the Windows unit. Example below, as well as updating the static buffer to test the reading:

// ULONG and LARGE_INTEGER are defined in Windows unit
type
  ENTRY          =  packed record
     seq:        ULONG;              
     time:       LARGE_INTEGER;
     text:       Array [0..0] of Char;
  end;
  PENTRY         =  ^ENTRY;

// Please update with correct buffer size declaration
const
  MAX_STORE      =  1024; // ???? No define was given for MAX_STORE

// Variables for status length and static buffer
var
  StatsLen:      DWORD;
  Stats:         Array [0..MAX_STORE] of Char;

// Return smaller of the 2 addresses
function MinAddr(Addr1, Addr2: PChar): PChar;
begin
  if  Addr1 < Addr2 then
     result:=Addr1
  else
     result:=Addr2;
end;

// This is the code used for reading entries from the static buffer
procedure TestRead;
var  lpszEntry:     PChar;
     lpszLimit:     PChar;
     ulLen:         ULONG;
begin

  // Get adddress of stats buffer
  lpszEntry:=PChar(@Stats);

  // Determine upper pointer limit
  if (StatsLen > SizeOf(Stats)) then
     lpszLimit:=lpszEntry + SizeOf(Stats)
  else
     lpszLimit:=lpszEntry + StatsLen;

  // While current address < upper limit
  while (lpszEntry < lpszLimit) do
  begin
     // Get the length of the null terminated string
     ulLen:=StrLen(PENTRY(lpszEntry)^.text);
     // Display string
     MessageBox(0, PENTRY(lpszEntry)^.text, 'Read', MB_OK);
     // Increment by 4 bytes so we can calculate 32bit offset
     Inc(ulLen, 4);
     // Perform 32 bit alignment
     ulLen:=ulLen and $FFFFFFFC; // +1 for null-terminator +3 for 32bit alignment
     // Add in the seq and time fields
     Inc(ulLen, SizeOf(ULONG) + SizeOf(LARGE_INTEGER));
     // Increment current address to next entry
     Inc(lpszEntry, ulLen);
  end;

end;

// Sample code to update the static buffer so you can test the reading
procedure TestWrite;
var  lpszEntry:     PChar;
     lpszLimit:     PChar;
     ulLen:         ULONG;
     i:             ULONG;
begin

  // Get adddress of stats buffer
  lpszEntry:=PChar(@Stats);

  // Set upper pointer limit
  lpszLimit:=lpszEntry + SizeOf(Stats);

  // Test string to write
  i:=10000;

  // Set status len
  StatsLen:=0;

  // While current address < upper limit
  while (lpszEntry < lpszLimit) and (i < 10009) do
  begin
     // Set sample entry
     PENTRY(lpszEntry)^.seq:=i;
     PENTRY(lpszEntry)^.time:=LARGE_INTEGER(DateTimeToTimeStamp(now));
     // Copy sample text
     StrPCopy(PENTRY(lpszEntry)^.text, IntToStr(i));
     // Get string length
     ulLen:=StrLen(PENTRY(lpszEntry)^.text);
     // Display string
     MessageBox(0, PENTRY(lpszEntry)^.text, 'Write', MB_OK);
     // Increment by 4 bytes so we can calculate 32bit offset
     Inc(ulLen, 4);
     // Perform 32 bit alignment
     ulLen:=ulLen and $FFFFFFFC; // +1 for null-terminator +3 for 32bit alignment
     // Add in the seq and time fields
     Inc(ulLen, SizeOf(ULONG) + SizeOf(LARGE_INTEGER));
     // Increment current address to next entry
     Inc(lpszEntry, ulLen);
     // Update status length
     Inc(StatsLen, ulLen);
     // Next sample text to write
     Inc(i);
  end;

end;


// Calls to update the buffer with sample text and then read the entries back
TestWrite;
TestRead;

----

Regards,
Russell


0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
A company’s greatest vulnerability is their email. CEO fraud, ransomware and spear phishing attacks are the no1 threat to a company’s security. Cybercrime is responsible for the largest loss of money to companies today with losses projected to r…

929 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now