![]() |
Pointer & Co
Hi,
Ich versuche zur zeit gerade das hier: ![]() nach zu bauen... Leider stell ich mich ziemlich doof an... mir fehlt einfach die Erfahrung mit dem Arbeiten mit den Pointer/Buffer. In Delphi kann man sich ja davor ziemlich gut drücken :oops: Tja, jetzt wüsste ich halt gerne wie ich das unten zum laufen kriege... resp. wie ich den text auslesen kann. Hab jetzt etliches über pointer gelsen aber wirklich verstanden hab ichs leider nicht und hoffe jetzt das ihr mir helfen könntet.
Delphi-Quellcode:
Gruss Gibb
procedure TForm1.Button2Click(Sender: TObject);
var hSFMemory: hwnd ; SfAreaPtr: Pointer; MyResultPtr: Pointer; begin Try GetMem(MyResultPtr,1000); hSFMemory:= openfilemapping(FILE_MAP_READ,false,'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(MyResultPtr,SfAreaPtr, 1000); memo1.Text:= AnsiString(PChar(MyResultPtr)); end; Finally FreeMem(MyResultPtr); // FreeMem(SfAreaPtr); UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); End; end; |
Re: Pointer & Co
Erstmal würde ich es in eine eigene Unite verlegen,
dann sollte dich Delphi über die eventuell uninitialisierten Variablen verwarnt haben.
Delphi-Quellcode:
Außerdem willst du den Speicherbereich als Text auslesen, was wohl (laut dem Beispiel) nicht stimmt,
function GetSFString: String;
var hSFMemory: HWND; SfAreaPtr: PAnsiChar; begin hSFMemory := 0; SfAreaPtr := nil; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); Result := SfAreaPtr; end else Result := ''; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; schau dir das Beispiel nochmal genau an, such den Record (also den Aufbau der Daten in diesem Speicherbereich) raus und greife über diesen Record auf die Daten zu.
Delphi-Quellcode:
[add]
function GetSFString: ...;
var hSFMemory: HWND; SfAreaPtr: PSFRawMemMap; begin hSFMemory := 0; SfAreaPtr := nil; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); ... // SfAreaPtr^.irgendwas end else ...; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; @p80286: jupp, hab ich ... zumindestens etwas genauer überflogen :angel: |
Re: Pointer & Co
Hallo gibb
so könnte es funktionieren:
Delphi-Quellcode:
und wo liegen die Probleme bei Buffern und Pointern?
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var hSFMemory: hwnd ; SfAreaPtr: Pointer; MyResultPtr: Pointer; Bufferstr : string; begin setlength(bufferstr,1000); Try MyResultPtr:=@bufferstr[1]; hSFMemory:= openfilemapping(FILE_MAP_READ,false,'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin MyResultPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); //CopyMemory(MyResultPtr,SfAreaPtr, 1000); memo1.Text:= bufferstr; end; Finally // FreeMem(MyResultPtr); // FreeMem(SfAreaPtr); UnmapViewOfFile(myResultPtr); CloseHandle(hSFMemory); End; end; end. Ein Buffer ist ein Speicherbereich (Array, String ....) in den man Daten Schreibenkann und ein Pointer ist eine Adresse (diese Bereiches) z.B.
Delphi-Quellcode:
Gruß
var
Buffer : array [0..1023] of byte; BuffPtr : pointer; begin .... BuffPtr:=@Buffer[0]; .... end; K-H Edit: Da hat wohl jmd. das Beispiel besser gelesen als ich! |
Re: Pointer & Co
Hi und danke für die Antworten.
Also ich kenne den Record nicht unter VB daher nehm ich an das es sich darum handelt, leider scheine ich da auch nicht mit auf einen grünen Zweig zu kommen :-( Da es sich noch um ein test programm handelt mache ich mir noch keine weiteren Units.
Delphi-Quellcode:
Tja das klapt so jedenfalls auch nicht. unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type PSFRawMemMap = Record public Unknown: Integer; //'unbekanntes Tag NumTemps:Integer; //'Anzahl der Temperaturen NumFans: Integer; //'Anzahl der Lüfter NumVolts: Integer;// 'Anzahl der Spannungen Temps: Integer; //'Werte der Temperaturen Fans: Integer; //'Drehzahl der Lüfter Volts: Integer; //'Werte der Spannungen' end; TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } procedure GetTemps(); function FindWindowEx2(hParent: HWND; ChildClassName: string; ChildNr: Word): HWND ; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin GetTemps(); end; procedure TForm1.Button2Click(Sender: TObject); var hSFMemory: HWND; SfAreaPtr: Pointer ; MyResultRecord: PSFRawMemMap; begin hSFMemory := 0; SfAreaPtr := nil; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(Addr(MyResultRecord),SfAreaPtr,1000); memo1.Text := IntToStr(MyResultRecord.Fans); end; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; function TForm1.FindWindowEx2(hParent: HWND; ChildClassName: string; ChildNr: Word): HWND; var i: Word; hChild: HWND; begin hChild := 0; Result := 0; Dec(ChildNr); for i := 0 to ChildNr do begin hChild := FindWindowEx(hParent, hChild, PChar(ChildClassName), nil); if hChild = 0 then Break; Result := hChild; end; end; procedure TForm1.GetTemps(); var wndMain, wndChild: HWND; Text: PAnsiChar; MaxLength: Integer; begin wndMain := FindWindow('TForm1','SpeedFan 4.40'); if wndMain <> 0 then begin wndChild := FindWindowEx(wndMain, 0, 'TPageControl', nil); wndChild := FindWindowEx(wndChild, 0, 'TTabSheet', nil); wndChild := FindWindowEx2(wndChild,'TJvPanel', 3); MaxLength:= 1000; getWindowText(wndMain,Text,MaxLength); Memo1.Text:=Text; end; end; end. Das Zweite beispiel gibt auch nur KrimsKrams aus was aber anhand der ersten aussage kein Wunder ist ;) Danke jedenfalls euch beiden ;) Gruss Gibb |
Re: Pointer & Co
Wie finde ich anhand eines Pointers die speicherlänge auf die der Pointer verweisst heraus?
Gruss Gibb |
Re: Pointer & Co
Zitat:
woher weißt Du wie groß das Haus in 10034 Berlin, Bundesallee 12 ist? einPointer ist nur eine Adresse, zunächst einmal. es gibt auch typisierte Pointer, also Zeiger die auf Strukturen zeigen, und da bemißt sich die Größe nach der zu Grunde liegenden Struktur. Ich bin mir da nicht sicher aber das "MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0);" liefert doch nur garnichts (Daten) zurück!? Dann würde es mich auch nicht wundern wenn da nichts vernünftiges kommt. Zitat:
K-H |
Re: Pointer & Co
Naja ich schon nicht.. aber das Bauamt würde es sicher wissen. Aber wenn das nicht möglich ist frage ich mich wie das überhaupt funktionieren soll. Anhand deines vorherigen Beitrages bin ich davon ausgegangen das der Buffer das Haus währe der Pointer die adresse folglich müsste xy wissen wie gross der buffer ist wo die adresse hinzeigt.
Naja laut dem VB Code währe das ja so: MyAreaPtr = MapViewOfFile(MyAreaH, FILE_MAP_READ, 0, 0, 0) 'Pointer herausfinden CopyMemory VarPtr(mMyArea), MyAreaPtr, Len(mMyArea) 'und lesen! also der CopyMemory befehl sollte mir die daten in mMyArea kopieren. So versteh ich das zumindest. Ebenso in Delphi. nur dann hab ich die daten bei der adresse abgelegt weiss aber immer noch nicht wie drauf zuzugreifen. Gruss Gibb |
Re: Pointer & Co
Niemand mehr der mir sagen kann wie ich das angehen muss? Ich nehme schwer an das ich das mit dem Record auch falsch mache :-/
Ich habe leider echt keine ahnung wie das funktioniert :-( Der Herr der den VB Code geschrieben hat konnte ja sein Record irgendwie anpassen, ich nehme an das zeigt an wieviele daten wo zu gehören.. wie geht das denn in delphi? mir währ nichts solches bekannt. Ein Integer holt sich ja immer gleichviel speicher :-/ |
Re: Pointer & Co
Hallo Gibb,
nun mal langsam. Ich würde es so machen: erst einmal als Buffer ein Array of byte. Den dann Byte für Byte anschauen was wirklich rüber kommt, und dann ein record drüber legen.
Delphi-Quellcode:
Gruß
const
mbuff :=32 type tmyrecord : packed record feld1 : integer; feld2 : integer; .... end; var buffer : array [0..mbuff]; myrecord : tmyrecord absolute buffer; K-H edit: mbuff natürlich so groß wählen, das auf jeden Fall genug platz ist! und natürlich vor dem Lesen mit fillchar nullen! |
Re: Pointer & Co
Juhuu erste erfolge stellen sich ein :D
Folgender Code:
Delphi-Quellcode:
Liefert mir das hier zurück
unit Main;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type { PSFRawMemMap = Record public Unknown: Integer; //'unbekanntes Tag NumTemps:Integer; //'Anzahl der Temperaturen NumFans: Integer; //'Anzahl der Lüfter NumVolts: Integer;// 'Anzahl der Spannungen Temps: Integer; //'Werte der Temperaturen Fans: Integer; //'Drehzahl der Lüfter Volts: Integer; //'Werte der Spannungen' end; } TMyRecord = packed record public Unknown: Integer; //'unbekanntes Tag NumTemps:Integer; //'Anzahl der Temperaturen NumFans: Integer; //'Anzahl der Lüfter NumVolts: Integer;// 'Anzahl der Spannungen Temps: Integer; //'Werte der Temperaturen Fans: Integer; //'Drehzahl der Lüfter Volts: Integer; //'Werte der Spannungen' end; TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private public { Public declarations } end; const mbuff = 100; var Form1: TForm1; buffer : array [0..mbuff] of integer; myrecord : tmyrecord absolute buffer; implementation {$R *.dfm} procedure TForm1.Button2Click(Sender: TObject); var hSFMemory: HWND; SfAreaPtr: Pointer ; MyResultRecord: TMyRecord; i: Integer; txt: String; begin fillchar(buffer,1000,0); hSFMemory := 0; SfAreaPtr := nil; i := 0; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(Addr(buffer),SfAreaPtr,1000); while i < 99 do begin Text:= inttostr(buffer[i]); memo1.Text := memo1.Text + text+ #13+ #10; // IntToStr(MyResultRecord.Fans); inc(i); end; end; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; end. Zitat:
gruss Sev |
Re: Pointer & Co
Hi,
hab jetzt folgendes gemacht:
Delphi-Quellcode:
Wobei das scheint nicht zu stimmen, die einzige zahl die ich wiedererkenne währ numoftemps wobei diese so bei numofvolts eingetragen ist.
procedure TForm1.Button2Click(Sender: TObject);
var hSFMemory: HWND; SfAreaPtr: Pointer ; MyResultRecord: TMyRecord; i: Integer; txt: String; begin fillchar(buffer,1000,0); hSFMemory := 0; SfAreaPtr := nil; i := 0; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(Addr(buffer),SfAreaPtr,1000); MyResultRecord.Unknown:= buffer[0]; MyResultRecord.NumTemps:= buffer[1]; MyResultRecord.NumFans:= buffer[2]; MyResultRecord.NumVolts:= buffer[3]; MyResultRecord.Temps:= buffer[4]; MyResultRecord.Fans:= buffer[5]; MyResultRecord.Volts:= buffer[6]; end; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; Was macht dieser VB Code? oder was ist der gedanke dabei?: Zitat:
|
Re: Pointer & Co
Dein Record stimmt doch noch gar nicht :
Delphi-Quellcode:
Probier mal so
Private Type SF_Raw_MemMap
Unknown(5) As Integer 'unbekanntes Tag NumTemps As Integer 'Anzahl der Temperaturen NumFans As Integer 'Anzahl der Lüfter NumVolts As Integer 'Anzahl der Spannungen Temps(63) As Integer 'Werte der Temperaturen Fans(63) As Integer 'Drehzahl der Lüfter Volts(63) As Integer 'Werte der Spannungen End Type
Delphi-Quellcode:
TSF_Raw_MemMap = Packet Record
Unknown : Array[0..5] of Integer //unbekanntes Tag NumTemps : Integer //Anzahl der Temperaturen NumFans : Integer //Anzahl der Lüfter NumVolts : Integer //Anzahl der Spannungen Temps : Array[0..63] of Integer //Werte der Temperaturen Fans : Array[0..63] of Integer //Drehzahl der Lüfter Volts : Array[0..63] of Integer //Werte der Spannungen end; |
Re: Pointer & Co
Ah das is ein array in VB wenn eine klammer mit zahl angegeben wird..... dachte mir schon das die Zahlen für was sind, hab aber nicht geschnallt wofür. Hab das ja ettliche beiträge vorher schonmal geschrieben. Dank dir =D
|
Re: Pointer & Co
Die Array-Grenzen stimmen noch nicht :oops:
(5) ist 0..4 bzw 63 ist 0..62 laut ![]() Edit : Da sind sich die Leute nicht einig : ![]() Nach dem lesen der beiden Seiten : Die Arraygrenzen stimmen doch, die Zahl in der Klammer gibt den höchsten Index an und der Startindex ist normalerweise 0 wenn kein Option Base 1 angegeben ist |
Re: Pointer & Co
Naja, hilft aber auch nicht weiter wenn da nicht mehr daten stehen oder?
![]() ![]() PS: ich hab den buffer rausgeschmissen und versucht die daten gleich in den Record zu schreiben: CopyMemory(Addr(MyResultRecord),SfAreaPtr,1000); Sollte so doch auch stimmen, gibt mir ja die selben werte zurück nur bereits in die record struktur angepasst was meiner meinung nach ja unser ziel ist oder? |
Re: Pointer & Co
fillchar(buffer,1000,0); // Dein Buffer ist gar nicht so groß
RetVal.Temps = mMyArea.NumTemps RetVal.Volts = mMyArea.NumVolts RetVal.Fans = mMyArea.NumFans For x = 0 To 32 Step 2 RetVal.Temp(x / 2) = mMyArea.Temps(x) / 100 RetVal.Fan(x / 2) = mMyArea.Fans(x) RetVal.Volt(x / 2) = mMyArea.Volts(x) / 100 Next ist eine VB -Schleife, die die Integer aus den einzelnen Feldern in Floats umrechnet, wobei die Schrittweite 2 ist, also nur 16 Werte übertägt |
Re: Pointer & Co
Ist ein buffer immer wie ein Array aufgebaut?
Trozdem kommt nicht mehr als das hier: ![]() ![]() oberes bild ist mit:
Delphi-Quellcode:
aber direkt so scheint auch zu gehen:
CopyMemory(Addr(Buffer),SfAreaPtr,1000);
Delphi-Quellcode:
)
CopyMemory(Addr(MyResultRecord),SfAreaPtr,1000);
Was das erste bild zustande bringt, da hab ich den Buffer garnicht erst verwedet. Aber irgendwie scheine ich nicht alle daten zu kriegen ?? PS: wie kann ich z.b. die lenge von myResultRecord herausfinden? denn dann währe folgendes möglich:
Delphi-Quellcode:
Ich gehe ja davon aus das der record der form der Daten die ich zurückbekomme entsprechen sollte...
CopyMemory(Addr(MyResultRecord),SfAreaPtr,length(MyResultRecord));
|
Re: Pointer & Co
Hallo Gibb,
im Prinzip liegst Du schon richtig aber 1)Dein MyresultRecord muß ein packed record sein 2) statt Length solltest du Sizeof verwenden, das gibt Dir die Größe in Bytes zurück. z.B.
Delphi-Quellcode:
Gruß
a1 : array [0..3] of integer;
length(a1) >> 4 { 4 Integer} sizeof(A1) >> 16 {16 Bytes } K-H Edit: Tippfehler |
Re: Pointer & Co
1: isses doch:
Delphi-Quellcode:
Also scheint beim Copy was nicht ganz zu stimmen :-( oder sonstwo
TMyRecord = packed record
public Unknown : Array[0..5] of Integer; //unbekanntes Tag NumTemps : Integer; //Anzahl der Temperaturen NumFans : Integer; //Anzahl der Lüfter NumVolts : Integer; //Anzahl der Spannungen Temps : Array[0..63] of Integer; //Werte der Temperaturen Fans : Array[0..63] of Integer; //Drehzahl der Lüfter Volts : Array[0..63] of Integer; //Werte der Spannungen end; 2: danke das hab ich gesucht XD wusste nur nicht wie die funktion heisst ^-^' war mir schon klar das length nicht geht, aber du hast es verstanden ;) EDIT: Habs jetzt so:
Delphi-Quellcode:
EDIT2:
CopyMemory(Addr(MyResultRecord),SfAreaPtr,sizeof(MyResultRecord));
Was könnt hier nicht stimmen?
Delphi-Quellcode:
Das stimmt schon mit Addr von MyResultRecord oder?
hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM');
if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(Addr(MyResultRecord),SfAreaPtr,sizeof(MyResultRecord)); CopyMemory nimmt ja nur Pointers folglich geb ich ihm den Pointer zu meinem Record. :-/ |
Re: Pointer & Co
Also ich seh da jetzt keine Fehler, aber wie wäre es zb mit so etwas
Delphi-Quellcode:
und dann schau Dir mal den Inhalt von pMyRecord^ und MyResultRecord an, da sollte eigentlich das gleiche stehen.
Type
pMyrecord:=^TMyrecord; .... SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); pMyrecord:=SfAreaPtr; CopyMemory(Addr(MyResultRecord),SfAreaPtr,sizeof(MyResultRecord)); (ich hatte die Record Definition übersehen) Gruß K-H |
Re: Pointer & Co
Macht leider keinen Unterschied. :-( hab ich dann einfach die daten falsch strukturiert zurückgenommen?
Oder was muss ich Zaubern damit es stimmt ? Was vielleicht interessant sein dürfte ist das ich weder die volt angaben hab oder die fan angaben hier auf der HP kiste.(das einzige was ich hab sind 3 temps) aber das sollte doch dennoch stimmen im memory... sonst würde doch speedfan selber auch nicht funktionieren. Gruss Gibb |
Re: Pointer & Co
Wenn du folgende Deklaration benutzt, kommt was plausibles raus :
Delphi-Quellcode:
NumTemps : 3
TSF_Raw_MemMap = Packet Record
Unknown : Array[0..5] of SmallInt//unbekanntes Tag NumTemps : SmallInt //Anzahl der Temperaturen NumFans : SmallInt //Anzahl der Lüfter NumVolts : SmallInt //Anzahl der Spannungen Temps : Array[0..63] of Integer //Werte der Temperaturen Fans : Array[0..63] of Integer //Drehzahl der Lüfter Volts : Array[0..63] of Integer //Werte der Spannungen end; NumFans : 0 NumVolts : 0 Temps[0] = 3300 ( / 100 = 33°) Temps[1] = 2700 ( / 100 = 27°) Temps[2] = 2600 ( / 100 = 26°) Die Zahlen, die als Integer bei dir angezeigt werden als Hex : 01 00 01 00 92 01 00 00 5c 06 03 00 03 00 00 00 00 00 e4 0c 00 00 8c 0a 00 00 28 0A Als SmallInt : 01 00 = 1 01 00 = 1 92 01 = 402 00 00 = 0 5c 06 = 1628 03 00 = 3 03 00 = 3 00 00 = 0 00 00 = 0 Rest als Integer : e4 0c 00 00 = 3300 8c 0a 00 00 = 2700 28 0A 00 00 = 2600 Edit : Ich hab hier auch ne HP-Kiste stehen, die hat auch fast nix an Sensoren |
Re: Pointer & Co
Hier noch eine etwas ausführlichere Deklaration:
Delphi-Quellcode:
Packet Record :wink:
TSharedMem = packed record
Version : Word; {2 Byte} Flags : Word; {2 Byte} MemSize : Integer; {4 Byte} Handle : THandle; {4 Byte} NumTemps : Word; {2 Byte} NumFans : Word; {2 Byte} NumVolts : Word; {2 Byte} Value : array[0..0] of Integer; end; Edit: Ob tatsächlich statisch 64 oder 32 Einträge für Temps usw. vorgesehen sind oder die Anzahl der Werte dynamisch und die Zuordnung zu Temp, Fan und Volt sich entsprechend verschiebt, ist zumindest mir nicht klar. |
Re: Pointer & Co
Hallo zusammen,
Danke vielmals ich jetzt funktionierts, (ist noch nicht ganz ausgereift der Code, aber so funktionieren die Grundlegenden sachen... wollte diesen auch mit der öffentlichkeit teilen ;))
Delphi-Quellcode:
Gruss Gibb
unit Main;
interface uses Windows, SysUtils, Classes, Forms, Controls, StdCtrls; type TMyRecord = Packed Record Unknown : Array[0..5] of SmallInt;//unbekanntes Tag NumTemps : SmallInt; //Anzahl der Temperaturen NumFans : SmallInt; //Anzahl der Lüfter NumVolts : SmallInt; //Anzahl der Spannungen Temps : Array[0..63] of Integer; //Werte der Temperaturen Fans : Array[0..63] of Integer; //Drehzahl der Lüfter Volts : Array[0..63] of Integer; //Werte der Spannungen end; TForm1 = class(TForm) Memo1: TMemo; Button2: TButton; procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; const mbuff = 1000; var Form1: TForm1; buffer : array [0..mbuff] of integer; myrecord : tmyrecord absolute buffer; implementation {$R *.dfm} procedure TForm1.Button2Click(Sender: TObject); var hSFMemory: HWND; SfAreaPtr: Pointer ; MyResultRecord: TMyRecord; i: Integer; begin fillchar(buffer,1000,0); hSFMemory := 0; SfAreaPtr := nil; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(Addr(MyResultRecord),SfAreaPtr,sizeof(MyResultRecord)); memo1.Text:= memo1.Text+'Number Of Temps:'+inttostr(MyResultRecord.NumTemps)+#13+#10; memo1.Text:= memo1.Text+'Number Of Fans:'+inttostr(MyResultRecord.NumFans)+#13+#10; memo1.Text:= memo1.Text+'Number Of Volts:'+inttostr(MyResultRecord.NumVolts)+#13+#10; For i:= 0 to MyResultRecord.NumFans -1 do begin MyResultRecord.Fans[i]:= MyResultRecord.Fans[i]div 100; memo1.Text:= memo1.Text+'Fan'+inttostr(i)+':'+inttostr(MyResultRecord.Fans[i])+#13+#10; end; For i:= 0 to MyResultRecord.numTemps -1 do begin MyResultRecord.Temps[i]:= MyResultRecord.Temps[i]div 100; memo1.Text:= memo1.Text+'Temp'+inttostr(i)+':'+inttostr(MyResultRecord.Temps[i])+#13+#10; end; For i:= 0 to MyResultRecord.NumVolts -1 do begin MyResultRecord.Volts[i]:= MyResultRecord.Volts[i]div 100; memo1.Text:= memo1.Text+'Fan'+inttostr(i)+':'+inttostr(MyResultRecord.Volts[i])+#13+#10; end end; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; end. PS: Ja ich weiss sollte nicht mit div arbeiten ;) aber war gerade zu faul das alles vom int umzuwandeln. |
Re: Pointer & Co
hallo Zusammen,
Ich hab jetzt das hier in eine eigene unit ausgelagert:
Delphi-Quellcode:
unit ReadSpeedfanData;
interface uses Windows, SysUtils, Classes, Forms, Controls, StdCtrls, Dialogs, messages; type TResultIntRecord = Packed Record Unknown : Array[0..5] of SmallInt;//unbekanntes Tag NumTemps : SmallInt; //Anzahl der Temperaturen NumFans : SmallInt; //Anzahl der Lüfter NumVolts : SmallInt; //Anzahl der Spannungen Temps : Array[0..63] of Integer; //Werte der Temperaturen Fans : Array[0..63] of Integer; //Drehzahl der Lüfter Volts : Array[0..63] of Integer; //Werte der Spannungen end; TResultStrRecord = Record NumTemps : SmallInt; //Anzahl der Temperaturen NumFans : SmallInt; //Anzahl der Lüfter NumVolts : SmallInt; //Anzahl der Spannungen Temps : TStringList; //Werte der Temperaturen Fans : TStringList; //Drehzahl der Lüfter Volts : TStringList; //Werte der Spannungen End; TReadSpeedfan = Class(TObject) Private FIntData : TResultIntRecord; FstrData: TResultStrRecord; Function UpdateData: Boolean; Public Function ReadSFData: Boolean; Function GetstrResult: TResultStrRecord; End; implementation Function TReadSpeedfan.ReadSFData: Boolean; var hSFMemory: HWND; SfAreaPtr: Pointer ; MyResultRecord: TResultIntRecord; begin hSFMemory := 0; SfAreaPtr := nil; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(Addr(MyResultRecord),SfAreaPtr,sizeof(MyResultRecord)); FintData:= MyResultRecord; Result:= True; If UpdateData = False then Result:= False; end else begin Result := False; end; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; Function TReadSpeedFan.UpdateData: Boolean; var i: Integer; Temp : Single; PiAsStr: String; Begin Try If not Assigned(FstrData.Temps) then FstrData.Temps:= TStringlist.Create; If not Assigned(FstrData.Fans) then FstrData.Fans:= TStringlist.Create; If not Assigned(FstrData.Volts) then FstrData.Volts:= TStringlist.Create; FstrData.Temps.Clear; FstrData.Fans.Clear; FstrData.Volts.Clear; For i:= 0 to FIntData.NumFans -1 do begin FstrData.Fans.Add('Fan'+inttostr(i)+':'+IntTostr(FIntData.Fans[i])); end; For i:= 0 to FIntData.NumTemps -1 do begin FstrData.Fans.Add('Temp'+inttostr(i)+':'+FormatFloat('###,##', fintData.Temps[i]/100)); end; For i:= 0 to FIntData.NumVolts -1 do begin FstrData.Fans.Add('Voltage'+inttostr(i)+':'+FormatFloat('###,##', fintData.Temps[i]/100)); end; FstrData.NumTemps:= FIntData.NumTemps; FstrData.NumFans:= FIntData.NumFans; FstrData.NumVolts:= FIntData.NumVolts; Result:= True; except Result:= False; End; End; Function TReadSpeedfan.GetstrResult (): TResultStrRecord; var MyResultRecord: TResultStrRecord; i: Integer; begin Result := FstrData; end; end. Und ruffe es aus dem Main auf:
Delphi-Quellcode:
Sobald er aber die Funktion abschliessen möchte kommen exceptions. Ich nehme an das es irgendwie an dem Copymemory befehl und nicht freigegeben speicehr resp. bereits freigegeben Speicher liegt. Hat da jemand ne ahnung was genau das problem ist?
procedure TForm1.Button2Click(Sender: TObject);
var SpeedFanReader : TReadSpeedfan; begin SpeedFanReader.Create; Speedfanreader.ReadSFData; SpeedFanReader.free; sleep(1); end; Gruss Sev |
Re: Pointer & Co
Ach du meine güte -.- mann sollte wissen wie man ein objekt erzeugt -.-'
Sorry, Lösung fürs problem (und ich hab ca ne stunde dafür verbraten -.-):
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var SpeedFanReader : TReadSpeedfan; begin SpeedFanReader:= TReadSpeedfan.create; //SpeedFanReader.Create; <- alt war so -.- Speedfanreader.ReadSFData; SpeedFanReader.free; sleep(1); end; |
Re: Pointer & Co
hi,
irgendwas stimmt da noch nicht :-( Laut VB code werden die Return werte durch 100 geteilt bis auf die fans. Das hier sind jetzt die werte die ich kriege ohne zu teilen (bis auf die temps natürlich die sind bereits durch 100 ) ![]() stimmt in diesem fall etwas am array nicht? Komisch ist auch das er mir sagt er hätte 9 numofvolts aber danach doch nur 6 werte dafür hat. Gruss Sev |
Re: Pointer & Co
niemand eine Idee? Lese ich die werte falsch aus? Stimmt der datentyp nicht? beim vb code versteh ich auch nicht wieso der ein Step2 drinnen hat. Bei mir kommt schön brav immer eine Zahl nach der anderen, wenn ich nen step 2 reintun würde würde ich die hälfte der werten verlieren.
Gruss Sev |
Re: Pointer & Co
Delphi-Quellcode:
Warum nicht :
CopyMemory(Addr(MyResultRecord),SfAreaPtr,sizeof(MyResultRecord));
FintData:= MyResultRecord; Result:= True;
Delphi-Quellcode:
CopyMemory(Addr(FintData),SfAreaPtr,sizeof(MyResultRecord));
Result:= True;
Delphi-Quellcode:
Boolsche Werte nie auf True oder False abfragen :
If UpdateData = False then Result:= False;
![]() Besser :
Delphi-Quellcode:
bzw an der Stelle kannst du gleich schreiben
If Not UpdateData then Result:= False;
Delphi-Quellcode:
Result := UpdateData
|
Re: Pointer & Co
was mich sowieso auf einen Fehler gebracht hat ;)
Delphi-Quellcode:
was aber schlussendlich dasselbe resultat zurückliefert ;)
Function TReadSpeedfan.ReadSFData: Boolean;
var hSFMemory: HWND; SfAreaPtr: Pointer ; MyResultRecord: TResultIntRecord; begin result:= False; hSFMemory := 0; SfAreaPtr := nil; try hSFMemory := OpenFileMapping(FILE_MAP_READ, False, 'SFSharedMemory_ALM'); if HSFMemory <> 0 then begin SfAreaPtr := MapViewOfFile(hSFMemory, FILE_MAP_READ, 0, 0, 0); CopyMemory(Addr(FintData),SfAreaPtr,sizeof(MyResultRecord)); result:= UpdateData; end; finally UnmapViewOfFile(SfAreaPtr); CloseHandle(hSFMemory); end; end; EDIT: Wieso die Volts nicht stimmen konnten lag daran:
Delphi-Quellcode:
hatte da FormatFloat('###,##', fintData.Temp[i]/100)
For i:= 0 to FIntData.NumVolts -1 do begin
FstrData.Volts.Add('Voltage'+inttostr(i)+':'+FormatFloat('###,##', fintData.Volts[i]/100)); end; |
Re: Pointer & Co
hi
Hab jetzt ne 30 Tage trial auf nem Rechner installiert um zu kapieren wo meine Daten hingehen. Ein Blick auf die Daten im Record erklärt wo sie sind ;) ![]() ![]() also, ich mir gedacht ich immitier euch und spiel einwenig mit den datentypen und habe aus den array of int ein array of smallint gemacht und kriege das hier:
Delphi-Quellcode:
TResultIntRecord = Packed Record
Unknown : Array[0..5] of SmallInt;//unbekanntes Tag NumTemps : SmallInt; //Anzahl der Temperaturen NumFans : SmallInt; //Anzahl der Lüfter NumVolts : SmallInt; //Anzahl der Spannungen Temps : Array[0..63] of smallint; //Werte der Temperaturen Fans : Array[0..63] of smallint; //Drehzahl der Lüfter Volts : Array[0..63] of smallint; //Werte der Spannungen end; ![]() ![]() Jetzt zwei fragen 1. wieso verhält es sich so ? Ich hab schon geschnallt das es mit der speichergrösse zusammenhängt mit welcher sich der datentyp sich reserviert. und folglich verschieben sich die Zahlen. Gibts noch mehr das man dazu wissen sollte? wie z.b. wie finde ich heraus welcher datentyp der richtige ist ohne lang drum herum zu probieren? oder sonstige theorie... ich würde mich da gerne noch einwenig vertiefen. Frage2: Wieso lässt er immer noch ne 0 zwischen den einträgen? Wofür ist diese da? Gruss GIBB |
Re: Pointer & Co
Mit SpeedFan 4.40 funktioniert bei mir diese Struktur (bzw. stimmt mit der Anzeige in SpeedFan überein):
Delphi-Quellcode:
Es sind maximal 32 Werte je Typ.
TSharedMem = packed record
Version : Word; // 2 Byte Flags : Word; // 2 Byte MemSize : Integer; // 4 Byte Handle : THandle; // 4 Byte NumTemps : Word; // 2 Byte Anzahl der Temperaturen NumFans : Word; // 2 Byte Anzahl der Lüfter NumVolts : Word; // 2 Byte Anzahl der Spannungen Temps : array[0..31] of Integer; // 32 * 4 Byte Werte der Temperaturen Fans : array[0..31] of Integer; // 32 * 4 Byte Drehzahl der Lüfter Volts : array[0..31] of Integer; // 32 * 4 Byte Werte der Spannungen end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz