0

ポインターを使用して、16 進数値で満たされたメモリ領域を移動しようとしています。uint8_t ポインターを使用して、一度に 1 バイトのみを指すようにしています。特定の位置 (開始位置からのオフセット数のバイト) に移動し、長さが 1、2、4、または 8 バイトのバイトのグループを格納したいと考えています。次に、値を符号付きまたは符号なしの 10 進数 (enum パラメーターによって決定) として解釈して出力したいと考えています。

ポインターを 1 バイトの uint8_t からバイト数の正しいサイズ (例: 8 btyes の場合は uint64_t) に単純に変更し、値を格納できると考えました (1 バイトだけを出力することはできないため)。時には、バイト/バイトのグループ全体を評価する必要があります)。これは私がこれまでに持っているものです:

void showValueAtOffset(FILE* Out, const uint8_t* const baseAddr, uint32_t Offset, Sign Sgn, uint8_t nBytes) {//------------------doesn't work----------------
   uint8_t *p = baseAddr;//create a pointer that points to the first byte of memory in the array
   for(int i = 0; i < Offset; i++){//use a for loop to move p to the location indicated by Offset 
       p++;
   }
   if(nBytes == 1){
       //pointer p already has the correct typecast for the number of bytes
       uint8_t N = *p;//store the value of the byte
       if(Sgn == SIGNED){
           int8_t result = N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
           fprintf(Out, "%u  ", N);//print the value
       }
   }
   else if(nBytes == 2){
       uint16_t q = (uint16_t) p;//create the pointer q with the correct typecast for the number of bytes
       uint16_t N = *q;//store the value of the bytes
       if(Sgn == SIGNED){
           int16_t result = N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
           fprintf(Out, "%u  ", N);//print the value
       }
   }
   else if(nBytes == 4){
       uint32_t q = (uint32_t) p;//create the pointer q with the correct typecast for the number of bytes
       uint32_t N = *q;//store the value of the bytes
       if(Sgn == SIGNED){
           int32_t result = N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
           fprintf(Out, "%u  ", N);//print the value
       }
   }
   else if(nBytes == 8){
       uint64_t q = (uint64_t) p;//create the pointer q with the correct typecast for the number of bytes
       uint64_t N = *q;//store the value of the bytes
       if(Sgn == SIGNED){
           signed int result = (signed int) N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
            unsigned int result = (unsigned int) N;
            fprintf(Out, "%u  ", result);//print the value
       }
   }
   else{
       //this should not happen according to the preconditions
   }
   fprintf(Out, "\n");
}

これは機能せず、「無効な型引数 'unary *' (have 'uint32_t')」や「警告: ポインターから異なるサイズの整数へのキャスト」などのいくつかのエラーが発生します。

私は何を間違っていますか?

4

1 に答える 1

2

エラーの直接の原因はuint16_t *q = (uint16_t *) p;、 ではなくを使用する必要があることですuint16_t q = (uint16_t) p;。つまり、ポインター型を別のポインター型に型キャストし、後で解決します。

それでも、変更されたコードはマシン アーキテクチャに依存しており、ビッグ/リトルエンディアンとアラインメントの問題があります。つまり、コードは x86 ボックスで動作しますが、アライメントされていないメモリ アクセスが原因でクラッシュしたり、他のアーキテクチャで間違った数値を生成したりする可能性があります。移植可能な方法は次のようになります。

uint32_t to_uint32_be(const void* num)
{
    const uint8_t *p = num;
    uint32_t res = 0U;
    int i;
    for (i = 0; i < 4; i++)
        res = (res << 8) + p[i];
    return res;
}

上記のコードで、「be」はビッグ エンディアンを表します。つまり、データは最上位バイトが最初のネットワーク バイト順で格納されます。

于 2015-04-03T23:54:58.823 に答える