2015-02-06 61 views
0

我想了解如何在Delphi中轉換類型,類似於C/C++。在Delphi中添加類型轉換指針

我試圖轉換的C++代碼是這樣的;

typedef struct tagEXT2_INODE 
{ 
    uint16_t i_mode;  /* File mode */ 
    uint16_t i_uid;  /* Low 16 bits of Owner Uid */ 
    uint32_t i_size;  /* Size in bytes */ 
    uint32_t i_atime;  /* Access time */ 
    uint32_t i_ctime;  /* Creation time */ 
    uint32_t i_mtime;  /* Modification time */ 
    uint32_t i_dtime;  /* Deletion Time */ 
    uint16_t i_gid;  /* Low 16 bits of Group Id */ 
    uint16_t i_links_count; /* Links count */ 
    uint32_t i_blocks;  /* Blocks count */ 
    uint32_t i_flags;  /* File flags */ 
    union { 
     struct { 
      uint32_t l_i_reserved1; 
     } linux1; 
     struct { 
      uint32_t h_i_translator; 
     } hurd1; 
     struct { 
      uint32_t m_i_reserved1; 
     } masix1; 
    } osd1;    /* OS dependent 1 */ 
    uint32_t i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ 
    uint32_t i_generation; /* File version (for NFS) */ 
    uint32_t i_file_acl;  /* File ACL */ 
// uint32_t i_dir_acl;  /* Directory ACL */ 
    uint32_t i_size_high;   /* This is used store the high 32 bit of file size in large files */ 
    uint32_t i_faddr;  /* Fragment address */ 
    union { 
     struct { 
      uint8_t l_i_frag; /* Fragment number */ 
      uint8_t l_i_fsize; /* Fragment size */ 
      uint16_t i_pad1; 
      uint16_t l_i_uid_high; /* these 2 fields */ 
      uint16_t l_i_gid_high; /* were reserved2[0] */ 
      uint32_t l_i_reserved2; 
     } linux2; 
     struct { 
      uint8_t h_i_frag; /* Fragment number */ 
      uint8_t h_i_fsize; /* Fragment size */ 
      uint16_t h_i_mode_high; 
      uint16_t h_i_uid_high; 
      uint16_t h_i_gid_high; 
      uint16_t h_i_author; 
     } hurd2; 
     struct { 
      uint8_t m_i_frag; /* Fragment number */ 
      uint8_t m_i_fsize; /* Fragment size */ 
      uint16_t m_pad1; 
      uint32_t m_i_reserved2[2]; 
     } masix2; 
    } osd2;     /* OS dependent 2 */ 
} __attribute__ ((__packed__)) EXT2_INODE; 


EXT2_INODE *src; 
char *inode_buffer; 
int inode_index, ret = 0; 

inode_buffer = (char *)malloc(4096); 


src = (EXT2_INODE *)(inode_buffer + inode_index); 

有人可以解釋一下這樣的src可以這樣嗎?如何在Delphi中執行相同的操作?

感謝

編輯: 這裏是我的Ext2索引節點的記錄; 類型

TExt2iNode = Record 
    i_mode : Word; 
    i_uid : Word; 
    i_size : Cardinal; 
    i_atime : Cardinal; 
    i_ctime : Cardinal; 
    i_mtime : Cardinal; 
    i_dtimes : Cardinal; 
    i_gid : Word; 
    i_links_count : Word; 
    i_blocks: Cardinal; 
    i_flags : Cardinal; 
    osd1 : Record 
     linux1 : Record 
     l_i_reserved1 : Cardinal; 
     end; 
     hurd1 : Record 
     h_i_translator: Cardinal; 
     End; 
     masix1 : Record 
     m_i_reserved1 : Cardinal; 
     End; 
    End; 
    i_block: array [0..EXT2_N_BLOCKS-1] of Cardinal; 
    i_generation : Cardinal; 
    i_file_acl : Cardinal; 
    i_size_high : Cardinal; 
    i_faddr : Cardinal; 

    osd2 : Record 
     Linux2 : Record 
     l_i_frag : Byte; 
     l_i_fsize : Byte; 
     i_pad1 : Word; 
     l_i_uid_high : Word; 
     l_i_gid_high : Word; 
     l_i_reserved2 : Cardinal 
     end; 
     hurd2 : Record 
     h_i_frag : Byte; 
     h_i_fsize : Byte; 
     h_i_mode_high : Word; 
     h_i_uid_high : Word; 
     h_i_gid_high : Word; 
     h_i_author : Word; 
     end; 
     masix2 : Record 
     m_i_frag:Byte; 
     m_i_fsize : Byte; 
     m_pad1 : Word; 
     m_i_reserved : array[0..1] of Cardinal; 
     end; 
    end; 
    End; 

這是我的Ex2分區記錄;

type 
    Ext2Partition = Class 
    private 
     handle: THandle; 
     sect_size: Integer; 
     total_sectors: Int64; 
     relative_sect: Int64; 
     linux_name :AnsiString; 

     inodes_per_group: integer; 
     inode_size: integer; 
     block_size: integer; 
     totalGRoups: Integer; 
     desc : TExt2_Group_Desc; 

     last_block : Cardinal; 
     inode_buffer : array of AnsiChar; 
     root : Ext2File; 
     buffercache : TList; 
     lvol : LogicalVolume; 
    public 
     onview, is_valid: boolean; 
    published 
     Constructor Create(size, offset :int64; ssise: integer; PHandle: THandle); 
     function read_inode(inum: Cardinal):Ext2File; 
     function readblock(blocknum: cardinal; var buffer: array of AnsiChar):integer; 
     function mount():integer; 
    End; 

這是我的read_inode函數,其中指針計算髮生;

function Ext2Partition.read_inode(inum: Cardinal):Ext2File; 
var 
    group, index, blknum: cardinal; 
    inode_index : integer; 
    ret: integer; 
    fFile: EXt2File; 
    src: TExt2iNode; 
begin 
    if inum = 0 then 
    Result := NIL; 

    SetLength(self.inode_buffer, self.block_size); 

    group := (inum -1) DIV self.inodes_per_group; 

    if group > self.totalGRoups then 
    begin 
    //ShowMessage('Error reading iNode'); 
    Result := -1; 
    end; 

    index := ((inum-1) MOD self.inodes_per_group) * self.inode_size; 
    inode_index := (index MOD self.block_size); 
    blknum := self.desc.bg_inode_table + (index div self.block_size); 

    if blknum <> self.last_block then 
    ret := readblock(blknum, self.inode_buffer); 

    fFile := TExt2iNode.Create; 

    //What goes here? 

end; 
+0

這不是*類型轉換作爲類*。在將一個指針地址遞增到一個'struct'(Delphi中的記錄)之後,它會對內存內容進行類型轉換。 – 2015-02-06 20:48:10

回答

1

代碼分配一塊內存。在其他地方,它已經確定了該塊內某處的ext2 inode結構的偏移量,由​​給出。它將該偏移量添加到塊的開始處,給出結構的地址。代碼然後鍵入結果以告訴編譯器,計算出的char*地址實際上是該結構類型的地址。

使用直譯,我們就會有以下德爾福聲明:

var 
    inode_buffer: PAnsiChar; 
    inode_index: Integer; 
    src: PExt2_Inode; 

因此,分配src,您可以輸入鑄和C++代碼完全添加爲:

src := PExt2_Inode(inode_buffer + inode_index); 

大多數默認情況下,Delphi指針類型不支持這種指針算術,但PAnsiChar是特殊的。

使用您的翻譯,到目前爲止,其中inode_buffer是一個數組,而不是指向一個內存塊,你不是有這樣的:

src := PExt2_Inode(@inode_buffer[inode_index]); 

這索引數組,然後使用@運營商獲取該數組元素的地址。 (實際上,如果inode_buffer也是我的原始PAnsiChar類型,則可以使用相同的語法。)

+0

感謝您的輸入。我已經在存儲'inode_buffer'的地方添加了我的Ext2分區記錄。我用過'AnsiChar數組'。 – 2015-02-06 22:41:08

+0

使用指針而不是「ansichar」數組有什麼好處嗎?也嘗試你的建議,我得到一個編譯錯誤 - 「無效的類型轉換」。 – 2015-02-06 22:49:41

+0

沒有,只要你在控制內存分配的方式和時間。 (如果你不能控制,那麼別人爲你分配內存,然後你得到你給的任何東西,這通常是來自'malloc'或'GetMem'的簡單內存塊)。 Byte',但是。你不存儲文本,所以'Byte'是比'Char'更適合的類型。 – 2015-02-06 22:55:58