2012-09-20 3 views
1

내가 FORTRAN의 원시 프로그래머이기 때문에 미리 지식이 부족한 것에 대해 사과드립니다. 나는 바이너리 파일을 인제 스트 (ingest)하는 디버그 용 C 코드를 받았고, 작업중인 Fortran 프로그램을 위해 수백 개의 레코드 (정확하게는 871 개)가 들어있는 입력 파일로 파싱했다. 문제는 이러한 입력 바이너리 및 관련 c 코드가 Windows 환경에서 작성된 것입니다. 코드가 872 패킷을 얻을 때윈도우에서 생성 된 바이너리 데이터 파일을 리눅스로 변환

SAGE_Lvl0_Packet GetNextPacket() 
{  

    int i; 
    SAGE_Lvl0_Packet inpkt; 
    WORD    rdbuf[128]; 
    memset(rdbuf,0,sizeof(rdbuf)); 
    fprintf(stdout,"Nbytes: %u\n",Nbytes);//returns 224 
    if((i = fread(rdbuf,Nbytes,1,Fp)) != 1) 
     FileEnd = 1; 
    else  
    {   
     if(FileType == 0) 
      memcpy(&(inpkt.CCSDS),rdbuf,Nbytes);     
     else 
      memcpy(&inpkt,rdbuf,Nbytes); 
     memcpy(&CurrentPacket,&inpkt,sizeof(inpkt)); 
    } 
    return inpkt; 
} 

그래서,이 조각은 FileEnd는 = 1. 대신, 파서가 많은 양의 읽기를 시도 반환해야합니다 : 그것은 파일의 끝에 도달 할 때까지 파서 바이너리를 읽고 파일의 끝 (근처)에서 데이터. 이것은 아마도 프로그램이 충돌하게 만들 것입니다 (적어도 Fortran에서는 메모리의 다음 부분을 읽기 시작할 것입니까?) 다행히도 나중에 코드에 CRC가있어 파서가 ' 올바른 데이터를 읽고 정상적으로 종료하십시오.

Windows 바이너리의 바이너리 버퍼 크기와 값이 Linux에서보다 크거나 다른 문제가 있다고 가정합니다. 그렇다면 Windows 나 바이너리를 Linux 나 Linux로 변환하는 쉬운 방법이 있습니까? 내 가정에서 틀렸다면 아마 코드를 좀 더 살펴볼 필요가있을 것이다. BTW, WORD는 부호없는 short int이고 SAGE_Lvl0_Packet은 총 106 개의 WORD가있는 3-tier 구조입니다.

+0

아주 짧게 대답 : feof. – iced

답변

1

여기서 가장 큰 문제는 fread()이 파일 끝을 나타낼 때 FileEnd 플래그가 설정되지만 함수가 여전히 0 인 아웃 (유효하지 않은) 패킷을 반환하는 것입니다. 특별히 튼튼한 디자인은 아닙니다. 나는 방금 전에 반환 된 패킷을 사용하려고 시도하기 전에 호출자가 FileEnd을 검사해야한다고 가정하지만, 표시되지 않았기 때문에 잘못된 가정이 가능합니다.

또한 패킷이 어떻게 보이는지 알지 못하므로 다양한 memcpy() 호출이 올바른지 여부를 알 수 없습니다. memcpy()이 224 바이트를 212 바이트 길이의 구조로 복사하라는 요청을 받는다는 사실은 매우 문제가됩니다.

다른 문제가있을 수 있지만 지금은 큰 문제입니다.

+0

패킷의 실제 크기가 잘못되었을 수 있습니다. WORD PacketType : 10으로 정의 된 4 단어가 있기 때문에 이것을 말합니다.이 말은 PacketType이 10 비트 길이지만 PacketType이 여전히 16 비트 블록을 차지한다는 의미입니다. – DavidH

+0

그리고 나머지 코드는 게시하지 않아서 사과드립니다. 실망 할 수도 있습니다.하지만이 코드는 위성을 제어하는 ​​코드이므로 여기에 너무 많이 올려 놓고 싶지는 않습니다. – DavidH

관련 문제