2013-11-22 7 views
3

다음 코드를 고려없이 유니 코드 변환과 변이체 [바이트의 배열]할당 (델파이 XE2)에

function PrepData(StrVal: string; Base64Val: AnsiString): OleVariant; 
begin 
    Result := VarArrayCreate([0, 1], varVariant); 
    Result[0] := StrVal; 
    Result[1] := Base64Val; 
end; 

Base64Val base64로 (따라서 아니오 null 바이트)로 부호화 된 이진 값이다. (OleVariant) 결과은 클라이언트 응용 프로그램과 DataSnap 서버간에 자동으로 마샬링되어 전송됩니다.

Wireshark로 트래픽을 캡처하면 StrValBase64Val이 모두 유니 코드 문자열로 전송됩니다. 가능한 경우 Base64Val의 유니 코드 변환을 피하고 싶습니다. Variant 유형을 모두 살펴본 결과 문자 배열을 전송할 수있는 varString 이외의 문자는 표시되지 않습니다.

변형 배열 배열을 만드는 방법을 보여주는 this question이 있습니다. 나는이 기술을 AnsiString 대신에 사용할 수 있다고 생각하고있다. 그러나 유니 코드 문자열로 변환하지 않고 Variant에 비 유니 코드 문자 데이터의 배열을 할당하는 또 다른 방법이 있습니까?

답변

4

Delphi의 구현은 맞춤 변형 유형 코드를 사용하여 Variant에 AnsiString 및 UnicodeString을 저장하는 것을 지원합니다. 이 코드는 varString 및 varUString입니다.

그러나 interop는 일반적으로 표준 OLE 변형을 사용하며 OLE 문자열 varOleStr은 16 비트 인코딩입니다. 그것은 당신의 관찰을위한 이유 인 것처럼 보일 것입니다.

16 비트 텍스트로 변환하지 않으려면 데이터를 바이트 배열로 저장해야합니다. 이렇게하면 base64 인코딩이 무의미 해집니다. 페이로드를 인코딩하는 base64를 중지하고 바이너리를 바이트 배열로 보냅니다. 질문의 예와 유지

+0

짧은 문자열을위한 AFAIR. AnsiString에 대한 varLString // PS : 어떤 이유로 든 이진 스트림이 실행될 수없고 base64가 너무 무거울 경우 yEnc 인코딩이 있습니다. –

+0

@Arioch 아니요, 긴 문자열입니다. –

+0

제대로 작동합니다. Base64를 사용하지 않고 OleVariant에 정렬 된 PVarArray를 통해 이진 데이터를 전송합니다. 데이비드의 다른 답변에 대한 참조를 포함하여 답변을 별도로 게시하겠습니다. 여기서 그는 대부분의 작업을 수행하는 방법을 보여주었습니다. –

1

, 이것은 (내 질문에 참조로 다른 질문에 David's answer에서 코드와 주석을 사용하여) 나는 그것을 작동하게하는 방법입니다 DataSnap 서버에 다음

function PrepData(StrVal: string; Data: TBytes): OleVariant; 
var 
    SafeArray: PVarArray; 
begin 
    Result := VarArrayCreate([0, 1], varVariant); 
    Result[0] := StrVal; 
    Result[1] := VarArrayCreate([1, Length(Data)], varByte); 
    SafeArray := VarArrayAsPSafeArray(Result[1]); 
    Move(Pointer(Data)^, SafeArray.Data^, Length(Data)); 
end; 

, I Value을 가정하면,이 같은 OleVariant에의 이진 데이터를 추출 할 수있는 것은 OleVariant에 변형 배열 Result[1]이다 ".이 코드 varString 및 varUString는"

procedure GetBinaryData(Value: Variant; Result: TMemoryStream); 
var 
    SafeArray: PVarArray; 
begin 
    SafeArray := VarArrayAsPSafeArray(Value); 
    Assert(SafeArray.ElementSize=1); 
    Result.Clear; 
    Result.WriteBuffer(SafeArray.Data^, SafeArray.Bounds[0].ElementCount); 
end; 
+0

여기에 약간의 비대칭 성이 있습니다. 코드의 첫 번째 섹션에는'SizeOf()'가 포함되지만 두 번째 섹션에는 포함되지 않습니다. 요소가 1 크기의 바이트라는 것을 알기 때문에 어느 쪽도 필요하지 않습니다. 그러나 컴파일러가 variant 배열의 내용을 보장 할 수 없기 때문에 아마도 코드의 두 번째 블록에 온 전성 검사를 추가해야합니다. +1하고 왜 귀중한 지에 대한 설명에 대해 이전에 삭제 된 의견에 감사드립니다. 나는 시도하고 당신이주의했다는 것을 기쁘게 생각합니다. :-) –

+0

감사합니다 @ 데이비드 - 당신은 ** 왜 ** ** 설명하기 위해 시간을 주셔서 감사합니다. 나는 당신이 제안한 것처럼'SizeOf()'를 추가하려했지만'SafeArray.Data'의 요소에 접근하는 방법을 알 수는 없습니다. 그래서 양쪽에'SizeOf (Byte)'를 추가했다. 비록 완벽하지는 않지만 ... –

+0

대답을 편집하여 내가해야한다고 생각하는 것을 보여 주시겠습니까?그것을 설명하는 것보다 쉬울 것입니다. –