![]() |
Strings über COM-Port Senden über einen Pointer
Hallo Leute,
ich habe vor geraumer Zeit eine COM-Port Komponente auf das neue Delphi 2010 umgestellt und bisher hat sie auch gut funktioniert bis jetzt. Es ist ein Fehler aufgetreten den ich mir nicht erklären kann. Wenn ich einen String der zum Beispiel '$PFAL,Sys.Cnf.Reset' so aus sieht sende macht er alles wie er es soll. Aber wenn der String '$PFAL,CNF.Set,AL14=GPS.Nav.sSpeed>=1&sys.timer.e0 &Sys.Timer.s4=inactive&Sys.Timer.s5=running:GPS.Hi story.Write,0,"&(IMEI),B:,10,1,,,,,&(Can3),,,,,C:, 11,4,0,7,4,,&(Can10),&(Can9),,,,,,E:,6,1,&(speed.c mps),&(Fieldstrength),&(Alt),&(DOP),&(SatsUsed),"' so aus sieht. Dann schneidet er beim senden den mittel Teil heraus. Das einzige was eine Erklärung dafür wäre ist das die Länge des Pointers nicht korrekt ist, die ich vorher berechne. Hier ist die Funktion die ich zum senden benutze:
Delphi-Quellcode:
Hat jemand hier eine Erklärung dafür?
function TCommPortDriver.SendString( s: AnsiString ): boolean;
var DataPtr: Pointer; Size: Cardinal; begin Result := False; DataPtr := nil; try Size := Length( s ) + 1 * SizeOf( PAnsiChar ); GetMem( DataPtr , Size ); Move( PAnsiChar( s )^ , DataPtr^ , size ); Result := SendData( DataPtr, size ) = size; finally FreeMem( DataPtr , size ); DataPtr := nil; end; end; |
Re: Strings über COM-Port Senden über einen Pointer
das müsste Size := Length( s ) + 1 * SizeOf( AnsiChar ); heißen. Du willst ja die Datenmenge die deine Zeichenkette im Speicher hat. Wenn du jetzt einen 32-bit-Pointer nimmst, müsstest du eigentlich 4x so viel haben???
Bernhard PS: Was ist die Mitte? Ich möchte jetzt nicht zählen, aber wie viele Zeichen hat denn der String? |
Re: Strings über COM-Port Senden über einen Pointer
Warum ist die Funktion eigentlich so kompliziert?
Das Kopieren des String in einen Puffer ist doch überflüssig.
Delphi-Quellcode:
function TCommPortDriver.SendString(const s: AnsiString ): boolean;
begin Result := SendData(PAnsiChar(s), Length(s) ) = Length(s); // je nach Deklaration von SendData könnte der Aufruf auch so aussehen // Result := SendData(s[1], Length(s) ) = Length(s); end; |
Re: Strings über COM-Port Senden über einen Pointer
@Bernhardt
Ein AnsiChar kann bis zu 4 Bytes im Speicher belegen deswegen kann man nicht einfach die Länge des Strings nehmen sonst führt das zu einem anderen Ergebnis. Mitte: Der String sieht dann so aus, wenn er am COM-Port raus kommt: $PFAL,CNF.Set,AL14=GPS.Nav.sSpeed>=1&sys.timer.e0& Sys.Timer.s4=inactive&Sys.Timer.s5=running:GPS.Hd. cmps),&(Fieldstrength),&(Alt),&(DOP),&(SatsUsed)," |
Re: Strings über COM-Port Senden über einen Pointer
Sorry, aber das ist Quatsch,
ein AnsiString ist ein Byte orientierter String, d.h. das Length(einAnsistring) genau die Länge in Bytes ergibt. Da muss man nicht mit Sizeof(Ansichar) arbeiten. Ich stimme sx2008 voll und ganz zu. Gruss |
Re: Strings über COM-Port Senden über einen Pointer
Gut Ok, aber trotzdem hat mir das noch nicht bei meinem Hauptproblem geholfen.
Das der String nicht mehr so aussieht wie ich ihn beabsichtige zu senden. Hier nochmal die Funktion SendData: (Diese hatte ich nicht verändert da Pointer ja nix mit den letzten Veränderungen im Delphi zu tun hatten)
Delphi-Quellcode:
// Sends binary data. Returns number of bytes sent. Timeout overrides
// the value specifiend in the OutputTimeout property function TCommPortDriver.SendDataEx(DataPtr: PChar; DataSize, Timeout: DWORD ): DWORD; var nToSend, nSent, t1: DWORD; begin // Do nothing if port has not been opened Result := 0; if not Connected then exit; // Current time t1 := GetTickCount; // Loop until all data sent or timeout occurred while DataSize > 0 do begin // Get TX buffer free space nToSend := OutFreeSpace; // If output buffer has some free space... if nToSend > 0 then begin // Check signals if FCkLineStatus and (GetLineStatus = []) then exit; // Don't send more bytes than we actually have to send if nToSend > DataSize then nToSend := DataSize; // Send WriteFile( FHandle, DataPtr^, nToSend, nSent, nil ); nSent := abs( nSent ); if nSent > 0 then begin // Update number of bytes sent Result := Result + nSent; // Decrease the count of bytes to send DataSize := DataSize - nSent; // Inc. data pointer DataPtr := DataPtr + nSent; // Get current time t1 := GetTickCount; // Continue. This skips the time check below (don't stop // trasmitting if the Timeout is set too low) continue; end; end; // Buffer is full. If we are waiting too long then exit if DWORD(GetTickCount-t1) > Timeout then exit; end; end; // Send data (breaks the data in small packets if it doesn't fit in the output // buffer) function TCommPortDriver.SendData( DataPtr: pointer; DataSize: DWORD ): DWORD; begin Result := SendDataEx( DataPtr, DataSize, FOutputTimeout ); end; |
Re: Strings über COM-Port Senden über einen Pointer
Bei SendDataEx solltest Du DataPtr:PAnsiChar verwenden, dann klappt das auch.
|
Re: Strings über COM-Port Senden über einen Pointer
Danke, an dieser Stelle hätte ich nicht gesucht. Weil ich dachte das es an der Umwandlung liegt.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 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 by Thomas Breitkreuz