Solved

How could i convert c soruce to Delphi ?

Posted on 2006-06-25
2
281 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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

746 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