AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

PChar wiederverwenden?

Ein Thema von moelski · begonnen am 8. Okt 2010 · letzter Beitrag vom 8. Okt 2010
Antwort Antwort
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#1

PChar wiederverwenden?

  Alt 8. Okt 2010, 13:41
Moin !

Ich habe da ein Stück Code was ich zum dynamischen Auslesen von Performance Countern nutzen möchte:
Delphi-Quellcode:
var _IndexA, _IndexB,
    _BufferSize : LongWord;
    _Res : PChar;
    _ValueName : String;
    _Status : PDH_STATUS;
begin
  _IndexA := 238; // (Processor) : 238
  _IndexB := 6; // (% Processor Time) : 6

  _BufferSize := 100;
  GetMem(_Res, _BufferSize);
  _Status := PdhLookupPerfNameByIndexW(Nil, _IndexA, _Res, _BufferSize);
  if _Status = ERROR_SUCCESS then begin
    Log('ValueName : ' + PChar(_Res));
    _ValueName := PChar(_Res);
  end else
    Log('Status : ' + IntToHex(_Status, 8));
  FreeMem(_Res);

  _res := NIL;

  GetMem(_Res, _BufferSize);
  _Status := PdhLookupPerfNameByIndexW(Nil, _IndexB, _Res, _BufferSize);
  if _Status = ERROR_SUCCESS then begin
    Log('ValueName : ' + PChar(_Res));
  end else
    Log('Status : ' + IntToHex(_Status, 8));
Nun bekomme ich über _Res den ermittelten Namen zurück in einem Buffer.
Beim ersten Aufruf klappt es auch. Aber beim zweiten kriege ich den Fehler das der Buffer zu klein wäre.
Das kann aber nicht sein, denn wenn ich nur den unteren Teil verwende klappt das wunderbar.

Es muss also an meiner Verwendung von _Res (PChar) liegen. Nur was ist da falsch?
Ob mit oder ohne _res := NIL spielt übrigens keine Rolle.
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#2

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 13:48
Moin !

Kanns mir selber beantworten ...

PdhLookupPerfNameByIndexW beeinflusst die Buffersize ... Und die ist danach zu klein für den zweiten Wert.

Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#3

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 13:51
Das riecht doch sehr danach, das _Buffersize nach der Rückkehr die Länge des Strings enthält. Also setz es neu und es sollte klappen.
Ich hab die Doku nur überflogen aber vllt. geht es auch so:
Delphi-Quellcode:
_res := NIL;
_Buffersize:=0;
_Status := PdhLookupPerfNameByIndexW(Nil, _IndexB, _Res, _BufferSize);
GetMem(_Res, _BufferSize);
_Status := PdhLookupPerfNameByIndexW(Nil, _IndexB, _Res, _BufferSize);
Gruß
K-H

zu spät (sniief)
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#4

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 13:53
Zitat:
zu spät (sniief)
Sorry aber dennoch danke
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#5

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 14:01
Das riecht doch sehr danach,
es riecht nicht nur ... das stickt schon richtig

Zitat von siehe MSDN/PSDK:
Size of the szNameBuffer buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned size to reallocate the buffer.
also schreib bitte _BufferSize div SizeOf(Char) , denn da wird nicht die Größe in Byte angegeben.

Heißt also, da du mit Delphi 2010 arbeitest, daß die 100 = 100 Zeichen aka 200 Byte entspricht.
also bei 50 bis 100 Zeichen würdest du dir einen Bufferoverrun einhandeln

OK, da es hier ein Var-Parameter ist, wäre es wohl einfacher, wenn du beim GetMem * SizeOf(Char) rechnest.


[add]
wobei ich auch gern mal einen anderen Weg geh
Delphi-Quellcode:
var _Index, _BufferSize : LongWord;
    _ValueName : String;
    _Status : PDH_STATUS;
begin
  _Index := 238; // (Processor) : 238
  _BufferSize := 0;
  PdhLookupPerfNameByIndex(Nil, _Index, Nil, _BufferSize);
  SetLength(_ValueName, _BufferSize - 1);
  _Status := PdhLookupPerfNameByIndex(Nil, _Index, PChar(_ValueName), _BufferSize);
  if _Status = ERROR_SUCCESS then
    Log('ValueName : ' + _ValueName)
  else
    Log('Status : ' + IntToHex(_Status, 8));

  _Index := 6; // (% Processor Time) : 6
  _BufferSize := 0;
  PdhLookupPerfNameByIndexW(Nil, _Index, Nil, _BufferSize);
  SetLength(_ValueName, _BufferSize - 1);
  _Status := PdhLookupPerfNameByIndexW(Nil, _Index, PChar(_ValueName), _BufferSize);
  if _Status = ERROR_SUCCESS then
    Log('ValueName : ' + _ValueName)
  else
    Log('Status : ' + IntToHex(_Status, 8));
Wenn du noch mehr solcher Werte ausließt, dann würde ich das Auslesen lieber in eine Funktion packen.

PS: du nutzt PChar (dynamisch) und PdhLookupPerfNameByIndexW (statisch) zusammen
entweder:
PAnsiChar + ...A
PWideChar + ...W
PChar + ...

Unter Anderem sowas ist für viele Fehler verantwortlich, welche es mit der Ansi-Unicode-Umstellung seit Delphi 2009 gibt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 8. Okt 2010 um 14:29 Uhr)
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#6

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 14:04
Nich schlagen
Ich habs ja noch früh genug selber gemerkt
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#7

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 14:26
Keine Sorge ... hab meinen Baseballschläger eh noch (im Laden) vergessen.

Und das "in TCHARs" nicht vergessen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#8

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 14:28
Inzwischen klappt alles:
Code:
[14:26:17] : \\XYZ\Processor(0)\% Processor Time
[14:26:17] : Value : 12,5
[14:26:17] : \\XYZ\Processor(1)\% Processor Time
[14:26:18] : Value : 6,1
[14:26:18] : \\XYZ\Processor(_Total)\% Processor Time
[14:26:18] : Value : 3,1
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#9

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 14:59
12,5 + 6,1 ist für mich aber ~9,3
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#10

AW: PChar wiederverwenden?

  Alt 8. Okt 2010, 15:15
Hast schon Recht, aber ich habe zwischen den Messungen je 500ms Pause gehabt.
Insofern passt deine Rechnung nicht
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz