Toon posts:

[Delphi] Size van een OleVariant bepalen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil in een DLL een willekeurige OleVariant (die door de hosting applicatie wordt aangeleverd) in z'n geheel en 'raw' kunnen opslaan in een BlobField in een tabel. Iets specifieker: in een field met DataType [image] in een MSSQL database.

Hoe ik normaliter een buffer via een MemoryStream in een BlobField krijg weet ik wel, dat is 't punt niet, maar...

Hoe bepaal ik hoe groot die OleVariant is???

Ik heb 't nu alleen nog maar getest met een OleVariant van 't type varString, en
- SizeOf(MyVariant) geeft altijd 16 terug, onafhankelijk van of 'ie nu een string van 2 of 2000 karakters bevat, en
- MyVariant.Size emmert over het feit dat 't geen automation object is.

Hopelijk zie ik iets heel simpels over het hoofd, maar ik kom er even niet uit...

Wanneer 't alleen maar om strings zou gaan, is 't simpel op te lossen (omzetten naar PChar, heb je meteen je buffer in 't goede formaat), maar ik wil het zo generiek mogelijk houden, dus ook voor bitmaps, etc.
En de aanroepende partij is in ASP/VBScript, dus ik zit een beetje vast aan OleVariants.

Verwijderd

Die 16 is de grootte van TVarData.

Ik denk dat je een case moet maken over TVarData(x).VType, dus zoiets:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{ Ik wist geen functie om de lengte van een PWideChar te
  berekenen, dus heb ik die zelf maar gemaakt :) }
function WideCharLen(S: PWideChar): Integer;
begin
  Result := 0;
  while S[Result] <> #0 do
    Inc(Result);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  A: OleVariant;
begin
  A := 'Hoi';
  ListBox1.Items.Add(Format('SizeOf(A) = %d', [SizeOf(A)]));
  ListBox1.Items.Add(Format('SizeOf(TVarData) = %d', [SizeOf(TVarData)]));
  case TVarData(A).VType of
    varOleStr:
    begin
      ListBox1.Items.Add('varOleStr');
      ListBox1.Items.Add(Format('Size = %d',
        [WideCharLen(TVarData(A).VOleStr)]));
    end;
  else
    ListBox1.Items.Add('Iets anders');
  end;
end;

Verwijderd

Topicstarter
DiFool, dank je!
Niet zozeer vanwege je voorbeeld, want die WideCharLen functie klopt niet. (Diep uit de online help van Delphi: "For PWideChar variables, the index is automatically multiplied by two.")

Maar je hebt me wel op 't goede spoor gezet. Ik had me nog nooit echt verdiept in Variants, en had dus nog niet echt naar TVarData gekeken. 'k Ben er nu achter dat je de uitgebreidere variants moet splitsen in de VarData (16 bytes), en de pointer naar de data zelf. En 't streamen van de belangrijkste Variants (vooral OleStr, in mijn geval) is me daarmee nu prima gelukt! :)

Verwijderd

Beetje heel late reactie, maar WideCharLen klopt wel;

[Ik kan het niet in de help vinden; maar hier ben ik vrij zeker van:]

S[x] is eigelijk S[x]^ en geeft de x-de WideChar; dus niet Char ofzo.

Hierdoor zal met stappen van 2 bytes door de PWideChar worden gelopen..

Dus deze functie telt het aantal widechars :)

[edit]
Oeps, dat had je dus al door :)

Maar TVarData is zo gedefinieerd:
code:
1
2
3
4
5
6
7
8
 TVarData = packed record
    VType: Word;
    Reserved1, Reserved2, Reserved3: Word;
    case Integer of
    ..
    varOleStr:   (VOleStr: PWideChar);
    ..
  end;

Dus TVarData(X).varOleStr geeft een PWideChar; dus moet je ook met stappen van 2 bytes tellen..