Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Strings: von C++ senden - in Delphi empfangen : WIE? (https://www.delphipraxis.net/99210-strings-von-c-senden-delphi-empfangen-wie.html)

hathor 8. Sep 2007 16:34


Strings: von C++ senden - in Delphi empfangen : WIE?
 
C++:
char *version;
int cpu0core0t;
...
version = "1.00";
cpu0core0t = 10; //dummy wert
etc.

wird ins Shared Memory geschrieben:

auslesen mit einem C++-Programm geht problemlos.

Mit einem Delphi-Programm kann ich nur Integer-Werte auslesen,
bei den Strings kommt nur Müll heraus.

Delphi-Quellcode:
type
  TSharedData = record
     cpu0core0t : Integer; //coretemp von cpu0,core0
   version: array [0..3] of char;
   ...
...

  with SharedData^ do
     Begin
        Memo1.lines.add(Inttostr(cpu0core0t));    //geht
      Memo1.lines.add(version);       //geht nicht

Torpedo 8. Sep 2007 16:39

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Keine Ahnung ob das dein Problem löst, aber:
"1.00" ist 5 Zeichen lang, nicht vier. "Strings" in C/C++ werden durch \0 (char(0)) abgeschlossen.

phXql 8. Sep 2007 16:41

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Versuchs mal mit einem PChar.

hathor 8. Sep 2007 16:44

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Memo1.lines.add(PChar(version));

Ergebnis:

üÿÿ‹ð‰w‰~ ÇF¤B

stoxx 8. Sep 2007 17:51

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Du castest ja auch auf einen PChar, willst aber einen String ...

probiers also mal mit

Memo1.lines.add(String(version));

hathor 8. Sep 2007 18:51

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Memo1.lines.add(String(version)); geht auch nicht

Olli 8. Sep 2007 18:55

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Wie wäre es denn hier einfach mal den relevanten Teil des C++-Programms zu posten, welches in der Lage ist es zu lesen. Ich habe hier nämlich dieses unbestimmte Gefühl, daß du uns hier bei weitem nicht alle Fakten gegeben hast und dennoch eine zufriedenstellende Antwort erwartest.

hathor 8. Sep 2007 19:06

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Delphi-Quellcode:
#include "stdafx.h"
#include <windows.h>
#include <string>
using namespace std;

struct TData { 
   char *version;
   int nr;
...
}

int main(int argc, char* argv[])

{
   const char* SHAREDMEMORYSEGMENTID = "CtMySiMcHa";
....
//write
   HANDLE host_handle;
   TData *host_data;
   host_handle =    CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,sizeof(TData),SHAREDMEMORYSEGMENTID);
   host_data = (TData*)MapViewOfFile(host_handle,FILE_MAP_WRITE,0,0,0);
   host_data->version = "erste";
   host_data->nr = 1;

//read

   HANDLE client_handle;

   TData *client_data;
   client_handle = OpenFileMapping(FILE_MAP_READ,false,SHAREDMEMORYSEGMENTID);
   client_data = (TData*)MapViewOfFile(client_handle,FILE_MAP_READ,0,0,0);

   printf("Inhalt des SM - version: %s\n",client_data->version);
   printf("Inhalt des SM - nr: %i\n",client_data->nr);
...
   UnmapViewOfFile(host_data);
   CloseHandle(host_handle);

   UnmapViewOfFile(client_data);
   CloseHandle(client_handle);

   flushall();
   getchar();   

   return 0;
}

Olli 8. Sep 2007 19:17

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Zitat:

Zitat von hathor
Code:
struct TData { 
   char *version;
   int nr;
...
}

Wenn das einfach sooo geschrieben wird, würde ja nur der Pointer auf die Zeichenkette in der MMF abgespeichert, genau den wichtigen Teil hast du also weggelassen, dennn logischerweise ist der Pointer nur innerhalb des aktuellen Prozesses gültig. Entsprechend muß die Zeichenkette irgendwoanders innerhalb der MMF abgespeichert sein, oder man kann auf sie eben nicht zugreifen.

hathor 8. Sep 2007 19:21

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
@Olli:

Was empfiehlst Du?

stoxx 8. Sep 2007 19:48

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Zitat:

Zitat von hathor
@Olli:

Was empfiehlst Du?


Dazu müsstest Du erstmal schreiben, was Du eigentlich machst !
Versuchst Du den C Quelltext nach Delphi zu portieren?
dann musst Du Dir einen ShortString in TDATA anlegen, kein Array of Char ..
vielleicht solltest Du noch etwas von Deinem Delphi Quelltext posten :-)

oder liest Du ein MMF Aus, was ein C++ Programm schreibt,
dann dann müsstest Du TSharedData eigentlich so definieren

Delphi-Quellcode:
TSharedData = packet record
   version : PChar;
   nr : Integer;
...

end;

und dann geht auch Dein

Memo1.lines.add(String(version));

wieder (damit wandelst Du den Pointer dann in einen Delphi String um)

Olli 8. Sep 2007 19:55

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Zitat:

Zitat von hathor
@Olli:

Was empfiehlst Du?

Okay, nehmen wir mal folgende Deklaration für die Struktur an:

Code:
struct TData { 
   char *version;
   int nr;
   int blubb;
}
sizeof(TData) wird dir 12 zurückgeben! Und nun schreiben wir da rein:

Code:
TData *pointer_auf_daten = ...;
pointer_auf_daten->nr = 1;
pointer_auf_daten->blubb = 0;
pointer_auf_daten->version = "Dieser String ist länger als 12 Zeichen";
Fällt dir was auf? Ich empfehle, daß du uns das fehlende Puzzle-Stück postest und dann können wir auch helfen ;)

hathor 8. Sep 2007 20:10

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
sizeof(TData) =8 !!!

Olli 8. Sep 2007 20:12

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Zitat:

Zitat von hathor
sizeof(TData) =8 !!!

Großartig, und 12 ist größer als 8. Ändert bisher nichts an meiner obigen Aussage.

hathor 8. Sep 2007 20:19

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Ich verstehe Dich nicht:

sizeof(TData) =8 in C++ und in Delphi!

Olli 8. Sep 2007 20:29

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Zitat:

Zitat von hathor
Ich verstehe Dich nicht:

sizeof(TData) =8 in C++ und in Delphi!

Ändert noch immer nichts. Dein Code:

Code:
CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,[color=red]sizeof(TData)[/color],SHAREDMEMORYSEGMENTID);
Ich würde sagen nach Adam Riese und Eva Klein hast du ein mathematisches Problem alle Daten eines Strings in nur 8 Byte unterzubringen, zumal ja in der Struktur - wie schon erwähnt - eben nicht der String selber sondern nur der Zeiger auf die Zeigenkette gespeichert wird.

Nochmal also: Wo also wird der String gespeichert?

hathor 8. Sep 2007 21:03

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Das Problem liegt m.E. nicht auf der C++- sondern der DELPHI-Seite.
Die Integer-Werte können korrekt ausgelesen werden - auch wenn Hunderte im Shared Memory sind,
das Problem sind nur die Strings!

Ich brauche nirgendwo bei C++ einen Speicher für den Zeiger auf die Zeichenkette - wenn die Daten im SHARED MEMORY sind, hat das C++ - Programm seinen Teil erfüllt.

Lossy eX 8. Sep 2007 21:22

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Mal so eine Frage am Rande. Was genau versuchst du da eigentlich? Handelt es sich dabei um zwei getrennte Anwendungen oder um eine Anwendungen und eine DLL? Denn irgendwie konnte ich nicht rausfinden was du da eigentlich genau vor hast.

Wenn es nur eine DLL ist dann kannst du problemlos mit pchar das Ganze erledigen.

Wenn es zwei getrennte Anwendungen sind dann solltest du dir vor Augen halten, dass der Speicher normal nur für die Anwendung in einem virtuellen Speicherbereich gemappt werden. Und Pointer eignen sich dafür als Übertragungsmedium nicht. Du müsstest als entsprechend die Daten des Strings in dem SharedMemory Bereich ablegen. So wie das bei Zahlen von Hause aus der Fall ist. Und beim Auslesen müsstest du daraus wieder einen Text machen. Muss aber gestehen ist nur eine Vermutung, denn mit Shared Memory habe ich bisher noch so gut wie nichts gemacht.

PS: Strings in Delphi haben noch 8 Bytes Nutzinformationen die sich VOR dem eigentlichen Pointer befinden.

Olli 8. Sep 2007 22:52

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Zitat:

Zitat von hathor
Das Problem liegt m.E. nicht auf der C++- sondern der DELPHI-Seite.
Die Integer-Werte können korrekt ausgelesen werden - auch wenn Hunderte im Shared Memory sind,
das Problem sind nur die Strings!

Wunderbar. Wenn du das schon weißt, warum fragst du dann? :roll:

Zitat:

Zitat von hathor
Ich brauche nirgendwo bei C++ einen Speicher für den Zeiger auf die Zeichenkette - wenn die Daten im SHARED MEMORY sind, hat das C++ - Programm seinen Teil erfüllt.

Ja das ist ja auch alles ganz toll, wenn du nur erstmal die eigentliche Zeichenkette und nicht nur den Zeiger abspeicherst. In dem bißchen Code, welches du gezeigt hast, habe ich nirgends auch nur annähernd gesehen, daß du die Zeichenkette "im SHARED MEMORY" speicherst. Vielmehr hast du eben den Zeiger in Prozeß X damit an Prozeß Y übergeben.

@Lossy eX: Waren es nicht sogar 12 Bytes? Ich entsinne mich auch eines Referenzzählers neben Länge und Zeiger. Aber ich habe kein Delphi zum Überprüfen hier.

Lossy eX 9. Sep 2007 10:48

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Olli: Also davor sieht es so aus. [Referänzzähler][Länge][Stringdaten] und evtl abschließendes [#0]. Dabei bin ich mir aber nicht sicher. Und der Pointer eines Strings zeigt auf den Anfang der Daten. Aber du brauchst natürlich auch noch eine Variable die den Pointer aufnimmt. ;)

hathor 9. Sep 2007 16:24

Re: Strings: von C++ senden - in Delphi empfangen : WIE?
 
Weil ich keine Lösung gefunden habe, Strings auf "einfache" Art von einem C++-Programm über SHARED MEMORY zu DELPHI zu senden, packe ich jetzt die Strings in ein Array:

C++:
char bdata[128];

DELPHI:
bdata: array [0..127] of Char;
Da passen z.B. 8 Strings von 16 Zeichen oder 16 Strings von 8 Zeichen hinein.
Damit funktioniert es super - und mein Problem ist gelöst.

Vielen Dank allen, die sich den "Kopf zerbrochen" haben!


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:08 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