2013-07-03 187 views
-3

我正在從非常遺傳的代碼遷移到32位到64位機器。它通常寫入文件的數據在32位工作正常,但在64位當我檢查文件時,發現它一般包含32位值的4位除法。我的意思是如果我們在32位機器上有80個值,那麼在64位機器上會有20個值(大多數情況下)。我查看了下面的一段代碼,無法理解一些功能。遷移C++代碼32位機器到64位機器

  1. 爲什麼我們在寫入File之前調用反轉函數。

  2. 逆向功能的目的是什麼。

  3. 在寫函數中,雖然我們有任何數據類型,但我們總是編寫one_ascii值。

我曾嘗試了一段一段代碼,幫我解釋問題briefly.Please讓 我知道如果我需要提供更多的信息。

class GdsHeader 
{ 
public: 
    unsigned short rlen; 
    char  record_type; 
    char  data_type; 
}; 

class GdsRecord 
{ 
public: 
#ifndef SWIG 
    union 
    { 
    short *two_int; 
    int  *four_int; 
    double *eight_real; 
    char  *one_ascii; 
// void *v; 
    }; 
#endif 
    int length; 

     GdsRecord(); // { v = 0; length = 0; } 
     ~GdsRecord() ;// { delete v; } 
    void len (int l, int type); 
}; 




    class GdsBlock 
    { 
     bool  valid_block(); 
     int  len; 

    public: 

     bool  record_unred; 
     int  header_ftell; 
     GdsHeader h; 
     GdsRecord r; 
     int  array_size; 
    // bool  re_read; 

    //   GdsBlock() { re_read = false; } 
       GdsBlock() { record_unred = false; header_ftell = 0; } 
     void  set (int rt, int dt, int sz) 
       {TBE; 
       h.record_type = rt; h.data_type = dt; 
       array_size = sz;  r.len (sz, dt);TBX; 
       } 
     int  read_header (FILE *); 
     void  read_block (FILE *); 

     void  write (FILE *); 
     void  prt(); 
    }; 



    void GdsRecord :: len (int l, int type) 
{ 

    switch (type) 
    { 
    case STREAM_Bit_array: 
    case STREAM_Short: l *= 2; break; 
    case STREAM_Long: l *= 4; break; 
    case STREAM_Double: l *= 8; break; 
    } 
    if (l > length) 
    { 
    l = ((l/8) + 2) * 8; 
    if (one_ascii) delete [] one_ascii; 
    one_ascii = new char[l]; 
    debug2.printf("GdsRecord::len new one_ascii len %d one_ascii %X\n",l, one_ascii); 
    length = l; 
    } 

} 


#ifndef sparc 
     static void reverse (int len, char *buf) 
     { 
      TBE; 
      char tmp[24]; 
     int i; 
      for (i = 0; i < len; i++) tmp[i] = buf[i]; 
      for (i = 0; i < len; i++) buf[i] = tmp[ (len - 1) - i]; 
      TBX; 
     } 
     inline void reverse (int len, short *s) { reverse (len, (char *) s); } 
     inline void reverse (int len, int *s) { reverse (len, (char *) s); } 
     inline void reverse (int len, double *s) { reverse (len, (char *) s); } 
     inline void reverse (int len, unsigned char *s) {reverse (len, (char *) s); } 
     #endif 

void GdsBlock :: write (FILE *outstr) 
{ 
TBE; 
debug.printf("GdsBlock::write %X\n",outstr); 
    int i, err; 
    char *c, tmp; 
    if (h.data_type == 3) 
    { 
     cout<<"Begin...blk.r.four_int[0] =>"<<r.four_int[0]<<endl; 
    } 
    if (!this) 
    error.printf_exit("GdsBlock::write error !this\n"); 

    if (!outstr) 
    error.printf_exit ("GdsBlock::write Error - outstr == 0\n"); 

    err = ferror(outstr); 
    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 
    if (err) 
    { { 
    char *s = strerror (err); 
    fclose (outstr); 
    error.printf_exit ("GdsBlock::write error - %s, errno %d\n", s, err); 
    } 
    switch(h.data_type) 
    { 
    case 0: /* NO DATA */ 
     h.rlen = 4; 
    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 
     break; 
     case 1: /* BIT ARRAY */ 
    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 
#ifndef sparc 
     reverse (2, &r.two_int[0]); 
#endif 
     h.rlen = (2 * array_size) + 4; 
     break; 
     case 2: /* TWO BYTE SIGNED INTEGER */ 
    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 
#ifndef sparc 
     for (i = 0; i < array_size; i++) reverse(2,&r.two_int[i]); 
#endif 
     h.rlen = (2 * array_size) + 4; 
     break; 
     case 3: /* FOUR BYTE SIGNED INTEGER */ 
    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 
#ifndef sparc 
     for(i = 0; i < array_size; i++) 
     { 
      cout<<r.four_int[i]<<endl; 
      int *temp = &r.four_int[i]; 
      reverse(4,temp); 
      //print_stacktrace(); 
      cout<<r.four_int[i]<<endl; 
      //r.four_int[i] = r.four_int[i] << 2 ; 
     } 

#endif 
     h.rlen = (4 * array_size) + 4; 
     break; 
     case 5: /* EIGHT BYTE REAL */ 
    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 
#ifndef FPC 
     for (i = 0; i < array_size; i++) getr ((CONV *) (r.eight_real + i)); 
#endif 
#ifdef FPC 
     for (i = 0; i < array_size; i++) fpc (r.eight_real + i); 
#endif 
     h.rlen = (8 * array_size) + 4; 
     break; 
     case 6: /* CHARACTER ARRAY */ 
    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 
     h.rlen = array_size + 4; 
     break; 
    default: 
     error.printf_exit("Error: bad record type %d in GdsBlock :: external\n", (int) h.data_type); 
     } 

    if (h.rlen % 2) 
    { 
    r.one_ascii[h.rlen] = 0; 
    h.rlen++; 
    } 

    cout<< __LINE__<<" "<<__PRETTY_FUNCTION__<<endl; 

    i = h.rlen - 4; 
#ifndef sparc 
    c = (char *) &h.rlen; 
    tmp = c[0]; 
    c[0] = c[1]; 
    c[1] = tmp; 
#endif 
    err = fwrite (&h, 1, sizeof (h), outstr); 
    if (err != sizeof(h)) 
    { 
    err = ferror(outstr); 
    if (err) 
     { 
     char *s = strerror (err); 
     fclose (outstr); 
     error.printf_exit ("GdsBlock::write error - %s, errno %d\n", s, err); 
     } 

    fclose (outstr); 
    error.printf_exit("Error: bad header fwrite in GdsBlock :: write\n"); 
    } 
#if 1 
    err = fwrite (r.one_ascii, 1, i, outstr); 
    if (err != i) 
    { 
    err = ferror(outstr); 
    if (err) 
    { 
     char *s = strerror (err); 
     fclose (outstr); 
     error.printf_exit ("GdsBlock::write error - %s, errno %d\n", s, err); 
     } 

    fclose (outstr); 
    error.printf_exit("Error: bad record fwrite in GdsBlock :: write\n"); 
    } 
#endif 
debug.printf("GdsBlock::write exit\n"); 
    TBX; 
} 
+1

你的第三個問題是它特定於應用程序,而不是C++問題。您和/或編寫此代碼的人員應該知道。 –

+0

同意你:) – user765443

+0

我想在發佈這個問題後,我意識到它可能是32位到64位的序列號問題。不確定但在讀後註釋 – user765443

回答

2

reverse()根據平臺反轉字節順序。此處顯示的似乎只有非SPARC版本的reverse()請參閱endianness

在寫入文件之前顛倒字節順序(即調用reverse())的原因是使文件格式平臺(即字節順序)獨立。

+0

反轉字節順序不會使其不依賴於字節序。只有8位編碼是獨立於字節序的。如果有字節翻轉,則存在字節序。 – rubenvb

1

這是一些非常糟糕的代碼。您在複製過程中也犯了一些錯誤:您複製了GdsRecord兩次,並且未聲明中的i變量。

無論如何,這似乎是應該做的事情(我並不完全確定它做的是正確的事情,這取決於GdsRecord::len的工作原理以及所有這些記錄不完整的領域的確切含義以及幻數是)以big-endian格式寫入int

但是,它似乎沒有寫入short s的big-endian,這很奇怪,因爲我非常肯定這意味着它不會在sparc/x86互操作性中起作用。我不確定sparc使用什麼樣的排序double s,所以這部分可能會或可能不會工作。另外,我不能拿出GdsBlock::write的讀數,如果類型不是char,那麼它不會只寫入數據。

相關問題