2017-05-18 1 views
0

우리 모두 한 프로젝트에서 Delphi를 사용하고 있으며 수년간 가지고 있습니다. 는하지만 우리는 PAnsiChar가 함께 사용되는 다음과 같은 구문을 본 적이 없다 그것은 무엇을 의미하는지 모르는 :이 Delphi PAnsiChar 코드는 무엇을 의미합니까?

이 recX 단지 2 바이트를로드처럼 보이는 디버거에서
buffer  : PAnsiChar 
recInstance : Byte 
recX   : smallint 
num_info  : integer 

// buffer loaded from a file... 

num_info := 0; 
// next two lines are a mystery 
recInstance := Byte(buffer[num_info*5]); 
recX := Byte(buffer[num_info*5+1])+256*Byte(buffer[num_info*5+2]); 

하지만 구문은 일치하지 않는 것 같습니다.

답변

2

PAnsiChar 은 항상 당신이 AnsiChar가에서 지적되고 액세스 할 수있는 좋은 특성뿐만 아니라 (바이트 AnsiChar의의) 배열처럼 인덱스 표기법을 사용하여 다음 AnsiChar들했다. 그것이 여기에서 사용되는 이유입니다.

요즘에는 {$POINTERMATH}이있는 최신 버전에서는 대신 동일한 색인 생성을 사용하는 PByte을 사용하려고합니다.

recInstance은 오프셋 numinfo*5에서 바이트가 할당되고 recX에는 하나의 단일 16 비트 값으로 다음 두 바이트가 할당됩니다. 레미는 암시로

buffer: PByte; 
n: Integer; 

... 

n := num_info * 5; 
recInstance := buffer[n]; 
recX := buffer[n+1] or (buffer[n+2] shl 8); // together a 16 bit value 

, 한 번 사용하는 모든 3 바이트를 읽을 수 :

type 
    PRec = ^TRec; 
    TRec = packed record 
    Instance: Byte; 
    X: Smallint; // a 16 bit (i.e. 2 byte) signed integer. 
    end; // total size: 3 bytes. 

var 
    MyRec: TRec; 

... 

    MyRec := PRec(@buffer[num_info * 5])^; 

PRec 주조 재를 현재 버전에서

, 그것은처럼 쓸 수있다 - @buffer[num_info * 5]에 의해 반환 된 주소를 TRec에 대한 포인터로 해석 한 다음 해당 주소를 역 참조하고 ( ^ 사용) 결과를에 할당합니다. MyRec. 즉

, @buffer[...]PRec(...) 그것이 TRec 것처럼 타입의 포인터로 PRecPRec(...)^, 즉 포인터에 3 바이트를 얻을 수 있음을 전환, 포인터이다.

MyRec.X은 이제 recX과 같으며 MyRec.Instance은 이제 원래 코드의 recInstance과 동일합니다.

+0

수동으로 바이트를 연결하는 대신'PSmallint' 타입 캐스트를 사용합니다 :'recX : = PSmallint (@buffer [n + 1]) ^;'또는 더 좋게는 압축 된 레코드를 정의하고 그에 대한 타입 캐스트를하십시오. 대신에 :'type PRec =^TRec; TRec = 압축 된 레코드 recInstance : Byte; recX : 작은 크기; 종료; ... var 버퍼 : PAnsiChar {또는 PByte}; rec : TRec; ... rec : = PRec (@buffer [num_info * 5]) ^;' –

+0

@Remy : 저도 그렇습니다. 그러나'PRec (@buffer [n]) ^'문법은 이미'PAnsiChar '의 사용법을 이해하는데 어려움을 겪고있는 누군가를 위해 IMO가 더 이해하기 힘들 기 때문에 실제로는 명확하게 밝히지 않을 것이라고 생각했습니다. 나는 물건을 가능한 한 간단하게 유지하고 싶었다. –

+0

'num_info times 5'오프셋입니까? 데이터 유형이 포인터이기 때문에 별표는 모든 사람을 버리는 것입니다. – AlG

0

Byte() 막 (비록 가능 오버플 효과를 차지하지 않음) 바이트 타입

마지막 코드 라인 2 바이트에서 recX 변수 두 바이트 형태 (여기서는 AnsiChar) 1 바이트 크기 값의 캐스팅 타입

int16var = byte1 + 256 * byte2 
//almost equivalent of 
(byte2 shl 8) or byte1 
관련 문제