AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Strings über COM-Port Senden über einen Pointer

Strings über COM-Port Senden über einen Pointer

Ein Thema von itblumi · begonnen am 29. Mai 2010 · letzter Beitrag vom 29. Mai 2010
Antwort Antwort
itblumi

Registriert seit: 28. Mär 2009
73 Beiträge
 
Delphi XE6 Professional
 
#1

Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 15:29
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:
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;
Hat jemand hier eine Erklärung dafür?
Jan
Ein neuer Tag bringt so einiges mit sich. Was auch immer es ist, es bleibt ein kleines Abenteuer.
  Mit Zitat antworten Zitat
Benutzerbild von rollstuhlfahrer
rollstuhlfahrer

Registriert seit: 1. Aug 2007
Ort: Ludwigshafen am Rhein
1.529 Beiträge
 
Delphi 7 Professional
 
#2

Re: Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 16:45
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?
Bernhard
Iliacos intra muros peccatur et extra!
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 17:46
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;
  Mit Zitat antworten Zitat
itblumi

Registriert seit: 28. Mär 2009
73 Beiträge
 
Delphi XE6 Professional
 
#4

Re: Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 18:27
@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),"
Jan
Ein neuer Tag bringt so einiges mit sich. Was auch immer es ist, es bleibt ein kleines Abenteuer.
  Mit Zitat antworten Zitat
Benutzerbild von thkerkmann
thkerkmann

Registriert seit: 7. Jan 2006
Ort: Pulheim Brauweiler
464 Beiträge
 
Delphi 2010 Professional
 
#5

Re: Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 18:51
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
Thomas Kerkmann
Ich hab noch einen Koffer in Borland.
http://thomaskerkmann.wordpress.com/
  Mit Zitat antworten Zitat
itblumi

Registriert seit: 28. Mär 2009
73 Beiträge
 
Delphi XE6 Professional
 
#6

Re: Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 19:21
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;
Jan
Ein neuer Tag bringt so einiges mit sich. Was auch immer es ist, es bleibt ein kleines Abenteuer.
  Mit Zitat antworten Zitat
Benutzerbild von thkerkmann
thkerkmann

Registriert seit: 7. Jan 2006
Ort: Pulheim Brauweiler
464 Beiträge
 
Delphi 2010 Professional
 
#7

Re: Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 20:21
Bei SendDataEx solltest Du DataPtrAnsiChar verwenden, dann klappt das auch.
Thomas Kerkmann
Ich hab noch einen Koffer in Borland.
http://thomaskerkmann.wordpress.com/
  Mit Zitat antworten Zitat
itblumi

Registriert seit: 28. Mär 2009
73 Beiträge
 
Delphi XE6 Professional
 
#8

Re: Strings über COM-Port Senden über einen Pointer

  Alt 29. Mai 2010, 20:41
Danke, an dieser Stelle hätte ich nicht gesucht. Weil ich dachte das es an der Umwandlung liegt.
Jan
Ein neuer Tag bringt so einiges mit sich. Was auch immer es ist, es bleibt ein kleines Abenteuer.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:35 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