AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi WM_COPYDATA & Array of Strings = Müll
Thema durchsuchen
Ansicht
Themen-Optionen

WM_COPYDATA & Array of Strings = Müll

Ein Thema von turboPASCAL · begonnen am 28. Dez 2008 · letzter Beitrag vom 29. Dez 2008
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#1

WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 18:10
Hi,

ich habe da mal ein Problemchen an dem ich schon den ganzen halben Tag sitze,
und das Problem ist das "Verschicken" eines dyn. Array of String.

Ich habe schon ein paar Varianten durch die leider nicht funktionieren wollen.

Beispel:

Delphi-Quellcode:
type
  TParamList = array of string;


// --- Sender ---
//...
    hMainFormWnd := FindWindow('TForm1', 'Test - Application');
    //...
    begin
      if hMainFormWnd <> 0 then
      begin
        CPData.dwData := 0;
        CPData.cbData := sizeof(ParamList);
        CPData.lpData := @ParamList[0];
        SendMessage(hMainFormWnd, WM_COPYDATA, WPARAM(Application.Handle), LPARAM(@CPData));
      end;
    end;
//...

// --- Empfänger ----
procedure TForm1.WMCopyData(var Msg: TWMCopyData);
var
  aParamList: TParamList;
  i, len, size: integer;
begin
  len := Msg.CopyDataStruct^.dwData;
  //size := Msg.CopyDataStruct^.cbData;
  Setlength(aParamList, len);
  aParamList := TParamList(Msg.CopyDataStruct^.lpData);


  for i := 0 to len-1 do
    ListBox1.Items.Add(aParamList[i]);
end;
Leider kommt beim Empfänger immer nur Müll an.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
quendolineDD

Registriert seit: 19. Apr 2007
Ort: Dresden
781 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 18:13
Intern ist ein String doch auch nur ein Zeiger auf Speicherbereich und enthält noch zusätzlich die Länge des Strings ... Nehm mal ein array of char.
Zumindest hatte ich das Problem bei der Implementierung von IPC über NamedPipes.
Lars S.
Wer nicht mit der Zeit geht, geht mit der Zeit.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 18:54
Ich würde das ganze über einen Memorystream lösen.
Schreiben:
1. Länge des Strings als 4-Byte-Integer in den Stream schreiben
2. Den Inhalt des Strings
3. In die Copydata-Struktur die Länge des Streams (Stream.Size) sowie die Adresse (Stream.Memory)
4. WM_COPYDATA-Message verschicken

Lesen:
1. MemoryStream instanitiieren und Zeiger zuweisen
2. 4-Byte Integer lesen und einen String mit SetLength (String, Länge) alloziieren
3. <Länge> Bytes aus dem Stream in den String lesen
4. Freuen, das es so einfach ist
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#4

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 19:07
Isch abe garkeine TMemoryStreame. ( Wäre ja zu einfach.)

Bald geb ichs auf und neme ein statisches Array.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 19:12
Zitat von turboPASCAL:
Isch abe garkeine TMemoryStreame. ( Wäre ja zu einfach.)
Du vielleicht nicht, aber dein Delphi. Oder hast Du auch kein Delphi? Alternativ kannst du auch ein Byte-Array nehmen und dort die zu übertragende Information hineinkopieren. Und Bytearrays hat nun wirklich Jeder.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#6

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 19:15
Mehr oder weniger für nonVCL optimiert. Daher keine Classes.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#7

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 19:19
Hallo,

1. Strings mit Längenangabe sind Pascal-spezifisch, gibts in C usw. nicht.
2. Variable Strings sind Delphi-spezifisch...
3. Variables Array mit variablen Strings gibts in anderen Sprachen dreimal nicht.

Und überhaupt sind Daten, die aus einem Zeiger und vom System dynamisch verwaltetem Speicher bestehen zum Datenaustausch herzlich ungeeignet.

Für alle Programmierer ausser Delphianer wären nullterminierte C-Strings die natürliche Datenform und als Array eine Folge davon mit Doppel-0 als Abschluss. So arbeitet WIN32 intern und auch Copydata dürfte damit keine Probleme haben. Ich verwende daher für den Verkehr mit der Aussenwelt gleich PChar oder wandle bei Bedarf um, anstatt mich mit TStrings u.ä. zu verrenken.

Gruss Reinhard
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#8

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 19:23
Um den Code mal mit Zahlen auszudrücken:
Zitat:
Delphi-Quellcode:
        CPData.cbData := sizeof(ParamList);
        CPData.lpData := @ParamList[0];
SizeOf(ParamList) liefert 4 zurück (da ParamList ein Zeiger auf ein dyn. Array ist)
@ParamList[0]: zeigt auf den ersten Zeiger auf einen String => Du kopierst die Zeiger von deinem Adressraum in Zeiger im anderen Adressraum, wo sie ins Nirvana zeigen. Die eigentlichen Stringdaten werden hierbei nicht kopiert.

Ein array of string ist (grob beschrieben) nichts anderes als:
Delphi-Quellcode:
type
  PStringArray = ^TStringArray
  TStringArray = array[0..MaxInt div SizeOf(Pointer) - 1] of string
was wiederum (grob beschrieben) nichts anderes ist als
Delphi-Quellcode:
type
  PStringArray = ^TStringArray
  TStringArray = array[0..MaxInt div SizeOf(Pointer) - 1] of PChar
Und wenn du das an WM_COPYDATA übergibst, werden halt nur die Zeiger statt der Daten kopiert. Also ist ein MemoryStream wohl die einfachste Variante das Problem zu lösen. Oder du schickst die Strings einzeln rüber.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#9

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 19:24
Bei Copydata gibst Du einen Speicherbereich und eine Länge an. Wie Du die Daten dort hineinschreibst, bleibt dir überlassen. Wenn es nur ein einziger String ist, dann geht das so:
Delphi-Quellcode:
CPData.dwData := 0;
CPData.cbData := Length (MyString);
CPData.lpData := @MyString[1];
SendMessage(hMainFormWnd, WM_COPYDATA, WPARAM(Application.Handle), LPARAM(@CPData));
Wenn man mehr verschicken will, z.B. Strukturen, muss man die irgendwie serialisieren. Dazu könnte man dann neben Memorystreams auch sowas wie JSON oder XML verwenden, beide sind Standards, wobei JSON weniger Footprint / Overhead erzeugt. Aber, ach, dann wächst die Anwendung ja wieder um ein paar Kb. Und das geht bei nonVCL ja nun wirklich nicht. Heutzutage programmiert man ja auch wie vor 40 Jahren, oder wie ein C-Eremit.

Aber eine Fräge hätt ich nöch: Wenn nonVCL sich auf die Visual Control Library bezieht, wieso verzichtest Du dann auf TMemoryStream? MemoryStreams sind doch nun wirklich unsichtbar. Non-Visuell sozusagen...
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#10

Re: WM_COPYDATA & Array of Strings = Müll

  Alt 28. Dez 2008, 19:34
"C-Eremit."

Naja, MemoryStream könnte ich mir batsteln aber dann bräucht ich mich ja nicht mer mit dem "array of string" herumärgern.

Zitat:
CPData.lpData := @MyString[1];
Ich habe schon einiges versucht, nur das noch nicht.


Zitat von alzaimar:
Aber eine Fräge hätt ich nöch: Wenn nonVCL sich auf die Visual Control Library bezieht, wieso verzichtest Du dann auf TMemoryStream? MemoryStreams sind doch nun wirklich unsichtbar. Non-Visuell sozusagen...
Der Dateigrösse wegen.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 18:23 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