Einzelnen Beitrag anzeigen

Sc0rpe

Registriert seit: 3. Mai 2021
7 Beiträge
 
Delphi XE6 Professional
 
#6

AW: OleVariant über TCP senden

  Alt 3. Mai 2021, 15:39
Okay der aktuelle versuch sieht nun so aus, dass ich mir über TVarData(OleVar).VArray^.Data den Pointer auf die Daten hole. Das scheint mir ein array of PWideString zu sein. Darüber iteriere ich nun und schreibe zuvor die Länge des Strings in den Memorystream. Das ganze läuft soweit auch fehlerfrei durch, nur bekomme ich beim Empfangen immer nur leere Strings in zu lesen. Was mache ich denn falsch?


Code:
function GetOleElementSize(oletype: Word): Integer;
begin
  case oletype of
    varDouble  : Exit(SizeOf(Double));
    varInt64    : Exit(SizeOf(Int64));
    varByte    : Exit(SizeOf(Byte));
    varWord    : Exit(SizeOf(Word));
    varLongWord : Exit(SizeOf(LongWord));
    varInteger : Exit(SizeOf(integer));
    varSmallint : Exit(SizeOf(SmallInt));
    varShortInt : Exit(SizeOf(shortint));
    varOleStr  : Exit(SizeOf(WideChar));
  end;
end;
Code:
function MemStrmToOleVariant(
  MemStr: TMemoryStream): OleVariant;
var
  ArrSize   : LongWord;
  ByteArr : PByteArray;
  OleData : array of PWideString;
  IsArray : WordBool;
  oleVarType : Word;
  NumBytes, I, StrLength : integer;
begin
  MemStr.Position := 0;
  MemStr.ReadBuffer(olevartype, SizeOf(olevartype));
  MemStr.ReadBuffer(IsArray, SizeOf(IsArray));
  MemStr.ReadBuffer(ArrSize, Sizeof(ArrSize));
  MemStr.ReadBuffer(NumBytes, SizeOf(NumBytes));
  Result := VarArrayCreate([0, ArrSize-1], oleVarType);
  ByteArr := VarArrayLock(Result);

  OleData := TVarData(Result).VArray^.Data;
  SetLength(OleData, ArrSize);
  try
    if oleVarType = varOleStr then
    begin
      for I := 0 to ArrSize-1 do
      begin
        MemStr.ReadBuffer(StrLength, SizeOf(StrLength));
        OleData[I] := AllocMem(StrLength * NumBytes);
        SetLength(OleData[i]^, StrLength);
        MemStr.ReadBuffer(OleData[I]^, StrLength * NumBytes);
      end;
    end
    else
      MemStr.ReadBuffer(ByteArr^, NumBytes);
  finally
    VarArrayUnlock(Result);
  end;
end;
Code:
function OleVariantToMemStrm(
  OleVar: OleVariant): TMemoryStream;
var
  ByteArr : PByteArray;
  ArrSize   : LongWord;
  IsArray : WordBool;
  oleVarType : Word;
  NumBytes : integer;
  I, StrLength : integer;
  S : PWideString;
begin
  Result := TMemoryStream.Create;
  try
    IsArray := VarIsArray(OleVar);

    ArrSize := VarArrayHighBound(OleVar, 1) - VarArrayLowBound(OleVar, 1) + 1;
    ByteArr := VarArrayLock(OleVar);
    oleVarType := VarType(OleVar) and varTypeMask;

    NumBytes := GetOleElementSize(oleVarType);   // Bytes per Element / in case of string bytes per char
    if oleVarType = varOleStr then
    begin
      ByteArr := TVarData(OleVar).VArray^.Data;
    end
    else
      NumBytes := NumBytes * ArrSize;

    try
      Result.Position := 0;
      Result.WriteBuffer(OleVarType, SizeOf(oleVarType));
      Result.WriteBuffer(IsArray, SizeOf(IsArray));
      Result.WriteBuffer(ArrSize, SizeOf(ArrSize));
      Result.WriteBuffer(NumBytes, SizeOf(NumBytes));
      if oleVarType = varOleStr then
      begin
        S := PWideString(ByteArr);
        for I := 0 to ArrSize-1 do
        begin
          StrLength := Length(S^);
          Result.WriteBuffer(StrLength, SizeOf(StrLength));
          Result.WriteBuffer(S^, NumBytes * StrLength); // schreibe den String
          Inc(S);
        end;
      end
      else
        Result.WriteBuffer(ByteArr^, NumBytes);
    finally
      if IsArray then
        VarArrayUnlock(OleVar);
    end;
  except
    Result.Free;
    Result := nil;
  end;

end;
  Mit Zitat antworten Zitat