mikrocontroller.net

Forum: Compiler & IDEs msgsnd mit variabler Text-Länge


Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

ich stehe vor einem echten C-Problem: Ich will mittels Message_Queues 
Daten verschicken. Nun verlangt die Fkt msgsnd (msg.h) einen Struktur 
mit einem char-Feld fester Länge. Mein Problem ist, das ich 
verschiedenste Daten hin und her schicken möchte. Manchmal sind es 5 
Zeichen... manchmal vielleicht 500. Als Auflage meines Profs habe ich 
darauf zu achten, das nicht sinnlos ein Feld von 500 Zeichen verschickt 
wird, wenn ich nur 5 benötige. Das Problem, die Anzahl kann sich zur 
Laufzeit verändern.
Meine Idee... ich habe eine Fkt... MESSAGE_SEND... die als Parameter 
einen bestimmten Integer Wert mitbekommt. Diesen Wert will ich IN der 
Funktion nutzen um die Structur für das msgsnd zu initialisieren 
ungefähr so:

...
void MESSAGE_SEND ( int LAENGE ){

 struct MSGBUF {
    int mtyp;
    char text[LAENGE|;
}

msgsnd()....
...

natürlich meckert er hier an der Stelle text[LAENGE| rum, von wegen 
Typumwandlung int zu const char* ungültig

wie bekomme ich es hin, das ich eben nur die Anzahl an Zeichen 
verschieke, die ich auch wirklich benötige? Damit zum Beispiel eben ein 
¨Mikrocontroller auf dem das Programm mal laufen soll nicht ständig 
unnötig Speicher benötigt?...

hoffe ihr köönt mir helfen. Eure Seie wurde mir von mehreren Quellen 
empfohlen.

LG Daniel

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum dann nicht den speicher zur laufzeit anfordern?

struct MSGBUF {
    int mtyp;
    size_t size;
    char* text;
}


MSGBUF data;
data.size = 5;
data.text = (char*)malloc( data.size );

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Peter

Danke für die schnell Antwort... ein Problem das ich vergessen hatte zu 
erwähnen, und die Sache erst so richtig kompliziert macht ist, daß ich 
die Daten zwischen zwei verschiedenen Prozessen (Programmen) austauschen 
muß. Diese Programme haben unterschiedliche Adressbereiche, daher kann 
ich in der Struktur auch nicht mit Zeigern arbeiten. Zumindest kommst da 
beim Emfpänger nur Blödsinn an. Auf das verwenden von Shared Memory 
wolle ich verzichten, da es eigentlich mehrere Prozesse werden soll, und 
dadurch der Speicherzugriff zur Laufzeit nicht wirklich vorhersehbar 
ist.

LG Daniel

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann geht es nicht, entweder im den maximalen Platz vorsehen oder mit 
zeigern arbeiten.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gibt es keine Möglichkeit bei der Erstellung eines char Feldes TEXT[XX] 
die Länge "XX" mit Hilfe einer Vairbale anzugeben?
Oder vielleicht auch TEXT[] zuerst zu definieren und anschließen 
mithilfe von irgendweiner Fkt (memset oder malloc) die Felddimension 
festzulegen?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> gibt es keine Möglichkeit bei der Erstellung eines char Feldes TEXT[XX]
> die Länge "XX" mit Hilfe einer Vairbale anzugeben?

nein, meines wissens nicht. Entweder macht es der Compieler oder man 
muss es zur Laufzeit mit zeigern machen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was macht die msgsnd mit ihrem Argument?

Du kannst natürlich die Struktur als ganzes dynamisch allokieren und ein 
bischen mit Casts rumtricksen. Man allokiert Speicher, der groß genug 
ist, für die Basisdatenstruktur + den Platz den der Text benötigt:
struct MSGBUF {
    int mtyp;
}

void SendString( const char* text )
{
  int textLen = strlen( text ) + 1;
  struct MSGBUF* msg = malloc( sizeof(struct MSGBUF) + textlen );
  char* msgText = (char*)msg + sizeof( *msg );

  msg->mtyp = STRING_MESSAGE;  // oder was auch immer
  strcpy( msgText, text );
  msgsend( msg, sizeof( *msg ) + textlen );
  free( msg );
}

das hier müsste auch funktionieren. Spart das geCaste
struct MSGBUF {
    int  mtyp;
    char msgText[0];
}

void SendString( const char* text )
{
  int textLen = strlen( text ) + 1;
  struct MSGBUF* msg = malloc( sizeof( struct MSGBUF) + textlen );

  msg->mtyp = STRING_MESSAGE;  // oder was auch immer
  strcpy( msg->msgText, text );
  msgsend( msg, sizeof( *msg ) + textlen );
  free( msg );
}

Aber aufpassen, dass du nicht in Probleme mit Alignment und Padding 
läufst.

Autor: Ruslan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> Auf das verwenden von Shared Memory
>
> wolle ich verzichten, da es eigentlich mehrere Prozesse werden soll, und
>
> dadurch der Speicherzugriff zur Laufzeit nicht wirklich vorhersehbar
>
> ist.

Hi,

kannst du doch, wenn du Semaphoren verwendest, dann ist alles 
abgesichert gegen gleichzeitigen zugriff, und welche prozess auch immer 
zugreift, schnappt sich das token, liest oder schreibt und gibt das 
token wieder frei...

Ich denke das gerade SharedMemorie mit semaphoren deine probleme lösen 
sollten

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eventuell ist es ja auch sinnvoll zum Datenaustasuch eine Strukur mit 
das maximalen größe zu verwenden und intern mit zeigern zu arbeiten, 
wenn jetzt daten gesendet werden müssen dann einfach in die 
Sende-Struktur reinkopieren.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hänge mal hier die beiden funktionsschnipsel an...

//! Sende-Prozess 1
int WLME_WMIB_GET_REQUEST(int TEST){

  typedef struct PARABUF {
      int mtyp;
      int pid;
      char msg[TEST]; //!< message field
  };

  PARABUF para;

  int qid2;

  // Warteschlangen-ID
  qid2 = msgget(KEY_WLME, 0600);

  para.msg[0]='G';
  para.mtyp = 12;
  msgsnd(qid2, &para, sizeof (PARABUF), 0)

  return 0;
}

//! \Empfänger-Prozess 2
void GET_PARAMETER(int qid){

  //! \struct PARABUF structure for message transmit
  typedef struct PARABUF {
      int mtyp;
      int pid;
      char* msg; //!< message field
  };

  PARABUF parabuf;

  msgrcv(qid, &parabuf, sizeof(PARABUF), 12,IPC_NOWAIT)
}

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wäre vielleicht gut, wenn Du uns sagst um welche Plattform und 
welches OS es sich handelt und vor allem mal zumindest die Deklaration 
von msgsnd (msg.h), besser noch einen Link auf die Beschreibung postest.

Ich kenne OS die feste Längen voraussetzen und solche die Zeiger 
versenden. Im ersteren Fall haben die oft noch eine weitere Funktion für 
das versenden von Zeigern.
Aber das ist ja alles nur Vermutung.

Dann schreibst Du "Prozess (Programm)":
Es gäbe dann auch noch Threads. Und das hängt noch mit der Plattform und 
dem OS zusammen. Das müsste man genau wissen. Während Programme 
wahrscheinlich am besten über Pipes oder interne Porst kommunizieren, 
gibt es sicherlich auch Platformen in den der Speicher nicht von einer 
MMU  voneinander getrennt wird. Dann geht Karls Methode, sonst nicht.

Ansonsten hindert Dich nichts, in dem char Feld fester Länge einen 
Zeiger zu speichern. Die Gegenstelle muss nur wissen, was sie zu 
erwarten hat.

Also: Einfach mehr Informationen liefern, bitte.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich versuche mich mal an dem Vorschlag von Karl Hein und hänge aber 
trotzdem mal meine beiden Funktionsschnipsel hier an.

//! Sende-Prozess 1
int WLME_WMIB_GET_REQUEST(int TEST){

  typedef struct PARABUF {
      int mtyp; //!< \var int mtyp: defines direction for receive 
messages (2=to DME, 1=from DME)
      int pid;
      char msg[TEST]; //!< message field
  };

  PARABUF para;

  int qid2;

  // Warteschlangen-ID
  qid2 = msgget(KEY_WLME, 0600);

  para.msg[0]='G';
  para.mtyp = 12;
  msgsnd(qid2, &para, sizeof (PARABUF), 0)

  return 0;
}

//! \Empfänger-Prozess 2
void GET_PARAMETER(int BUFFERLENGTH, int qid){


  //! \struct PARABUF structure for message transmit
  typedef struct PARABUF {
      int mtyp; //!< \var int mtyp: defines direction for receive 
messages (2=to DME, 1=from DME)
      int pid;
      char* msg; //!< message field
  };

  PARABUF parabuf;

  msgrcv(qid, &parabuf, sizeof(PARABUF), 12,IPC_NOWAIT)
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> ich hänge mal hier die beiden funktionsschnipsel an...

Sieht so aus, als ob das passen würde :-)

Das ist das gute an C. Man kann alles hinkriegen, wenn man nur 
skrupellos aber kontrolliert vorgeht.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grrrr schrieb:

> MMU  voneinander getrennt wird. Dann geht Karls Methode, sonst nicht.

Es hängt alles davon ab, was dieses ominöse msgsend tatsächlich mit den 
übergebenen Daten macht und ob das Message Queue System mtatsächlich mit 
Messages unterschiedlicher Länge umgehen kann.

Die Schnipsel sind zwar kein Beweis, aber es sieht so aus, als ob das 
MSG System damit was anfangen kann.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also sorry für das doppelte senden der Funktionen... mein Internet hing 
gerade

Also ich verwende Ubuntu 8.04 und es sollte C- Programmiersprache sein 
(da ich mich hier am ehesten auskenne)

Die beiden Prozesse... sind wirklich eigenständige Programme... PThreads 
oder Folks fallen hier also leider raus.

Ich hatte bereits mal versuche eine Zeigeradresse mittels Char zu 
übertragen... hatte auch funktioniert.. nur ist eben dann beim Zugriff 
auf den Speicher eine Fehlermeldung zwecks Speicherverletzung gekommen.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> LeDan schrieb:
>> ich hänge mal hier die beiden funktionsschnipsel an...

an der Stelle mit dem msg[TEST] steigt er mir eben aus.. na ich versuche 
noch etwas weiter

über msgsnd sollen halt verschiedene Parameter übertragen werden, welche 
dann eben vom Empfängerprogramm ausgwertet werden sollen.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Es hängt alles davon ab, was dieses ominöse msgsend tatsächlich mit den
> übergebenen Daten macht und ob das Message Queue System mtatsächlich mit
> Messages unterschiedlicher Länge umgehen kann.

Habe ich ja geschrieben. :-{

LeDan schrieb:
> Ubuntu 8.04

Hmm. Platform wissen wir zwar immer noch nicht, aber es wird wohl was 
Intel-Artiges groesser als Pentium II sein.

Dann ist auch das erklärbar:

> Ich hatte bereits mal versuche eine Zeigeradresse mittels Char zu
> übertragen... hatte auch funktioniert.. nur ist eben dann beim Zugriff
> auf den Speicher eine Fehlermeldung zwecks Speicherverletzung gekommen.

Die Intels haben nämlich eine MMU, die vom Kernel auch fleissig benutzt 
wird um eben das zu verhindern, was Du gerade versuchst.

Poste doch mal welchen Compiler mit welchen Libs Du verwendest. Am 
besten einen Link auf die Doku posten. Dann können wir selbst gucken.

> Die beiden Prozesse... sind wirklich eigenständige Programme... PThreads
> oder Folks fallen hier also leider raus.
Jetzt fühle ich mich gerade veralbert. Sind es nun zwei Programme oder 
zwei Prozesse? Kennst Du den Unterschied? OK. "ps" zeigt Dir auch 
"Programme" an aber von OS-Sicht aus sind das im allgemeinen zwei paar 
Schuhe.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sind denn bitte "Folks"?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> Karl heinz Buchegger schrieb:
>> LeDan schrieb:
>>> ich hänge mal hier die beiden funktionsschnipsel an...
>
> an der Stelle mit dem msg[TEST] steigt er mir eben aus..

Ja. Klar.
Draum hab ich dir ja auch gezeigt, wie man das machen kann.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grrrr schrieb:
> Karl heinz Buchegger schrieb:
>> Es hängt alles davon ab, was dieses ominöse msgsend tatsächlich mit den
>> übergebenen Daten macht und ob das Message Queue System mtatsächlich mit
>> Messages unterschiedlicher Länge umgehen kann.
>
> Habe ich ja geschrieben. :-{

MMU hat nichts damit zu tun
Es geht darum, ob sich msgsend die Daten zwischenspeichert, bis sie 
übertragen wurden und ob der Übertragungsmechanismus mit 
unterschiedlichen Längen klar kommt.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Grrrr schrieb:
>> Karl heinz Buchegger schrieb:
>>> Es hängt alles davon ab, was dieses ominöse msgsend tatsächlich mit den
>>> übergebenen Daten macht und ob das Message Queue System mtatsächlich mit
>>> Messages unterschiedlicher Länge umgehen kann.
>>
>> Habe ich ja geschrieben. :-{
>
> MMU hat nichts damit zu tun

Doch. Auch.
Wenn nur Zeiger gesendet werden dann sind die auf einem System mit MMU 
von dem anderen Prozess/Programm/wasauchimmer wegen der MMU nicht 
verwendbar. Wenn die aber Daten sendet, dann schon. Aber ist denn dieses 
msgsend überhaupt geeignet über Prozess-/Programm-/wasauchimmer-Grenzen 
hinweg Daten zu übertragen?

Abgesehen von diesem kleinen "Konflikt" zwischen uns, leuchtet mir auch 
nicht ein was es bringen soll, der msgsend Funktion irgendeine Struktur 
beliebiger Länge aufzudrücken wenn Du nur eine bestimmte Länge kann. 
Woher weisst Du das msgsend als zweiten Parameter die Länge hat, oder 
kennst Du die Funktion? Wenn Du sie aber kennst, würde ich annehmen, das 
Du wüsstest was sie tut?

Mann, der Server hängt aber heute...

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Grrrr schrieb:
>> Karl heinz Buchegger schrieb:
>>> Es hängt alles davon ab, was dieses ominöse msgsend tatsächlich mit den
>>> übergebenen Daten macht und ob das Message Queue System mtatsächlich mit
>>> Messages unterschiedlicher Länge umgehen kann.
>>
>> Habe ich ja geschrieben. :-{
>
> MMU hat nichts damit zu tun

Doch. Auch.
Wenn nur Zeiger gesendet werden dann sind die auf einem System mit MMU 
von dem anderen Prozess/Programm/wasauchimmer wegen der MMU nicht 
verwendbar. Wenn die aber Daten sendet, dann schon. Aber ist denn dieses 
msgsend überhaupt geeignet über Prozess-/Programm-/wasauchimmer-Grenzen 
hinweg Daten zu übertragen?

Abgesehen von diesem kleinen "Konflikt" zwischen uns, leuchtet mir auch 
nicht ein was es bringen soll, der msgsend Funktion irgendeine Struktur 
beliebiger Länge aufzudrücken wenn Du nur eine bestimmte Länge kann. 
Woher weisst Du das msgsend als zweiten Parameter die Länge hat, oder 
kennst Du die Funktion? Wenn Du sie aber kennst, würde ich annehmen, das 
Du wüsstest was sie tut?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grrrr schrieb:

> leuchtet mir auch
> nicht ein was es bringen soll, der msgsend Funktion irgendeine Struktur
> beliebiger Länge aufzudrücken wenn Du nur eine bestimmte Länge kann.
> Woher weisst Du das msgsend als zweiten Parameter die Länge hat, oder
> kennst Du die Funktion? Wenn Du sie aber kennst, würde ich annehmen, das
> Du wüsstest was sie tut?

Als ich meinen ersten Vorschlag machte, wusste ich das noch nicht. Ich 
habs einfach mal angenommen, weil es anders nicht geht. Der TO hätte 
sich gemeldet, wenn das ein Problem wäre

Später dann kam die Bestätigung.
Beitrag "Re: msgsnd mit variabler Text-Länge"

> Mann, der Server hängt aber heute...

Ja. Das nervt.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl

Mist. Ich habe nicht geschaltet. Da Du die Daten kopierst, hat das mit 
einer MMU nichts zu tun. Das ist schon richtig.

Ich hätte eigentlich so auf Dich antworten müssen:

Ich meinte mit:
> vor allem mal zumindest die Deklaration
> von msgsnd (msg.h), besser noch einen Link auf die Beschreibung postest.
ausgedrückt zu haben, das alles von dem abhängt was die Funktion 
tatsächlich tut.
Das mit der MMU war nur ein Teilaspekt, berührt aber nicht die 
Hauptfrage.

Naja. Whatever... Schieb' mal ein Bier rüber.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Angebote schreiben macht mich durstig... :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grrrr schrieb:

> Ich meinte mit:
>> vor allem mal zumindest die Deklaration
>> von msgsnd (msg.h), besser noch einen Link auf die Beschreibung postest.
> ausgedrückt zu haben, das alles von dem abhängt was die Funktion
> tatsächlich tut.

Volle Zustimmung.
Ich habe eine Hypothese angenommen, die mir am logischten erschien: 
msgsend, sofern es mit unterschiedlichen Längen klarkommt, macht sich 
eine Kopie der Daten für seine eigene Queue. Damit darf ich meine eigene 
'lokale Variable' nach dem Aufruf wieder vernichten und es geht nur noch 
darum eine struct mit variabler Länge aus dem Speicher zu zaubern.


> Naja. Whatever... Schieb' mal ein Bier rüber.

 Bier << far_far_away

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also...

sorry für die verwirrungen in Programmiertechnischen Dingen bin ich noch 
nicht so sehr bewandert.. aber ich gebe mein bestes....

ich arbeite mit nem Intel Core2Duo Chip.

mit FOLKs meine ich die follk() funktion mit dessen Hilfe man ähnlich 
wie bei PTreads Childprozesse erstellen kann.

Ich arbeite mit 2 verschiedenen Programmen... eigentlich 3. Jeder 
simuliert bei mir eine Art Teil des OSI Schichtmodells die eben 
miteinander kommunizieren wollen.

Compilieren tue ich es im Moment immer mit g++ DME.cpp -o DME
hoffe mal das das so ok ist... ist für mich wie gesagt noch ziemliches 
Neuland.

Ich habe den Codehaufen mal als Zipgepackt hier angehangen.Zum 
verständnis... mit ALME_MSG_CLIENT.cpp übergebe ich nur einen Wert an 
die DME.cpp.. zum Beispiel 8 (das ist mein jetziger Testlauf)
die DME prüft den Wert... führt einige zuordnungen aus und übergibt 
wiederum eine entsprechende Routine an WLP.cpp. Diese soll mit nun eben 
in der Funktion WLME_WMIB_GET_REQUEST (WLP_FUNCTIONS/WLME_FUNCTION.h) 
einen Parameter an die DME zurückgeben. Dabei will ich nur versenden was 
auch wirklcih nötig ist, daher muß eben das char.msg Feld irgendwie 
dynamisch sein. In dem Beispiel sende ich nur erstmal einen Buchstaben 
zum Testen. Später sollen es dann ganze Zeichenketten sein, die eben in 
der Länge variieren.
Hoffe ihr seht bei dem Codehaufen durch. Aber vorweg schonmal Danke für 
eure Hilfe.

PS... bei der Lösung von Karl Heinz hänge ich gerade irgendwie fest... 
und er meckert von wegen Typverletzung mit meiner Struktur.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:

> mit FOLKs meine ich die follk() funktion mit dessen Hilfe man ähnlich
> wie bei PTreads Childprozesse erstellen kann.

kann es sein, dass du fork() meinst?

> PS... bei der Lösung von Karl Heinz hänge ich gerade irgendwie fest...
> und er meckert von wegen Typverletzung mit meiner Struktur.

Welcher genaue Code?
Welche exakte Fehlermeldung?

Ich habe das Codeschnipsel auch nur hier eingetippt und dabei übersieht 
man manchmal schon was.

Autor: LeDan (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
jetzt hab ich doch glatt die files vergessen

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja sorry.. ich meinte natürlich fork()... tststs... es ist Freitag.. 
verzeiht mir

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Message Mechanismus. Ist das der hier

http://opengroup.org/onlinepubs/007908775/xsh/sysmsg.h.html

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich gehe mal es hängt und steht alles nur mit in der Funktion 
WLME_WMIB_GET_REQUEST()  (/WLP_FUNCTIONS/WLME_FUNCTIONS.h)

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Dein Message Mechanismus. Ist das der hier
>
> http://opengroup.org/onlinepubs/007908775/xsh/sysmsg.h.html

das kommt mir arg bekannt vor... also JA.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> ich gehe mal es hängt und steht alles nur mit in der Funktion
> WLME_WMIB_GET_REQUEST()  (/WLP_FUNCTIONS/WLME_FUNCTIONS.h)

Was soll die eigentlich machen?
Wie kriegt sie den Text den sie übertragen soll?

Und wie sieht die Funktion jetzt aus? Hast du die dynamische Allokierung 
eingebaut, so wie ich dir das in einer der Musterlösungen gezeigt habe?


Zum Code gäbe es noch viel zu sagen. Aber das spar ich mir jetzt :-)

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Komisch, das einzige msgsnd das ich auf die schnelle finden konnte, kann 
variable Längen.

Du schriebst aber:
LeDan schrieb:
> Nun verlangt die Fkt msgsnd (msg.h) einen Struktur
> mit einem char-Feld fester Länge.

Wie bist Du darauf gekommen? Weil die Beispiele für die Struktur in der 
Message mit einer bestimmten Zahl als Feldgrösse dastehen?

Jedenfalls passt Karls Lösung dann doch.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich weiß ich weiß... ich bin ja auch noch Anfänger, also bitte nicht so 
streng sein.

der TEst der von oben kommt, soll dann mal später verarbeitet werden... 
spielt im Grunde für das eigentlich Problem erstmal keine Rolle.

Im Grunde wird es viele derartige Funktionen geben, einige senden eine 
feste Anzahl von Zeichen, die in verschiedenen Variablen gespeichert 
zusammngtragen wird, einige sollen eben Zeichen verschicken, deren 
Anzahl sich im Laufe des Betriebes verändert. (Es geht hier um 
Netzwerkverbindungen... Clients und Nodes... und die Anzahl der Clients 
variiert natürlich im Laufe der Zeit), mein Beispiel sendet derzeit nur 
erstmal ein einziges Zeichen um zu sehen wie es funktioniert.. dabei 
will ich aber eben gleich austesten, wie es variabel möglich ist. Da ich 
mir eben sonst an der Grundarchitektur des Programmes etwas anderes 
einfallen lassen muß... daher auch mein Hilfeschrei hier in diesem 
Forum. Mit shared memory könnte ich mir vorstellen, das es zu kristisch 
ist, da innerhalb eines Programmes verschiedene Funktionen gestartet und 
in einem childprozess laufen können, damit kann es eben Konflikte in der 
Laufzeit gben wenn ich gleichzeitig verschiedene Settings hin und 
herschicke und die Prozesse eben nicht stehen bleiben dürfen. Zur Not 
muß ich aber eben doch darauf zurückkommen. Hatte eben nur gehofft das 
ich es irgendwie mit den msgsnd und msgrcv hinbekomme.

ok... muß jetzt erstmal los.. bin aber später wieder online. danke 
nochmal für eure hilfe.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja. Das sind dann aber mindestens zwei Probleme, die Du da hast.
Das eine ist recht simpel. msgsnd kann variable Messagelängen.
Aber das andere ist ein Designproblem. Andere Ebene. Schreib doch mal 
was das Ganze soll.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> Mit shared memory könnte ich mir vorstellen, das es zu kristisch
> ist, da innerhalb eines Programmes verschiedene Funktionen gestartet und
> in einem childprozess laufen können, damit kann es eben Konflikte in der
> Laufzeit gben wenn ich gleichzeitig verschiedene Settings hin und
> herschicke und die Prozesse eben nicht stehen bleiben dürfen.

Warum sollen die nicht stehenbleiben? Schadet doch nichts. Und zur 
Synchronisation gibt es Semaphoren oder Messages etcpp.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok... hier also nochmal kurz besagte Funktion mit einer übetragung der 
Idee von Karl Heinz... zumidnest so wie ich es verstanden habe.

wenn ich die Funktion ersetzt und laufen lasse, kommt bei der DME eben 
nix oder was falsches an.

int WLME_WMIB_GET_REQUEST(char MSG[]){

  MSGBUF buf;

  struct PARABUF {
      int mtyp; //!< \var int mtyp: defines direction for receive 
messages (2=to DME, 1=from DME)
      int pid;
      char* msg; //!< message field
  };

  PARABUF para;
  para.msg=(char*)malloc(5);

  int qid;
  int qid2;
  int Zahl;

  Zahl=sizeof(WLPInfoBase);

  printf("zu übertragene Zahl: %d\n",Zahl);


  // Buffer leer räumen, damit kein Datenmüll übertragen wird
  memset(buf.msg,0,SIZE);


  // Warteschlangen-ID
  qid = msgget(KEY_WLME, 0600);
  qid2 = msgget(KEY_PLME, 0600);

  //! \TODO complete
  buf.msg[0]=(char)12;
  buf.msg[1]=Zahl&0x000000ff;
  buf.msg[2]=Zahl>>8&0x000000ff;
  buf.msg[3]=Zahl>>16&0x000000ff;
  buf.msg[4]=Zahl>>24&0x000000ff;

  para.msg[0]='G';
  para.mtyp = 12;
  printf("Größe des Strings %d\n", strlen(para.msg));
  msgsnd(qid2, &para, sizeof (PARABUF), 0);

  buf.mtyp = 999;
  msgsnd(qid, &buf, sizeof (MSGBUF), 0);

  printf("zu übertragen ist folgendes Zeichen: %d\n", para.msg[0]);

  printf("in WLME_WMIB_GET_REQUEST - out WLME_WMIB_GET_CONFIRM!!\n");

  //printf("Die Subfunktion WMIB erfolgreich an WLME_P 
übertragen!!\n");

  return 0;

}

meld mich dann später nochmal von wegen sinnhafitgkeit meines vorhabens.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> ich weiß ich weiß... ich bin ja auch noch Anfänger, also bitte nicht so
> streng sein.

Fang einfach mal damit an, das Namen komplett in Grossbuchstaben 
ausschliesslich für Makros reserviert sind. Nicht nur mir gehts so, dass 
mein Herzschrittmacher bei sowas
int WLME_WMIB_GET_REQUEST(int TEST){
erst mal aussetzt.

> Im Grunde wird es viele derartige Funktionen geben, einige senden eine
> feste Anzahl von Zeichen, die in verschiedenen Variablen gespeichert
> zusammngtragen wird, einige sollen eben Zeichen verschicken, deren
> Anzahl sich im Laufe des Betriebes verändert. (Es geht hier um
> Netzwerkverbindungen... Clients und Nodes... und die Anzahl der Clients
> variiert natürlich im Laufe der Zeit), mein Beispiel sendet derzeit nur
> erstmal ein einziges Zeichen um zu sehen wie es funktioniert.. dabei
> will ich aber eben gleich austesten, wie es variabel möglich ist.

Ist ja kein Problem.
Da baut man sich eine einzige Funktion, die mit variablen Datenlängen 
klar kommt und den tricky Teil enthält. Diese Funktion operiert einfach 
nur auf einem Bytefeld variabler Größe.

Und dann gibt es für verschiedene spezielle Datentypen eigene 
Funktionen, die ihre Argumente in geeigneter Form in diese eine 
spezielle Funktion hineinstopfen.

> Da ich
> mir eben sonst an der Grundarchitektur des Programmes etwas anderes
> einfallen lassen muß...

Musst du nicht.
msgsend kann das schon, du musst es nur richtig füttern. Und diese 
Aufgabe wiederrum kann diese eine spezielle Funktion übernehmen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> ok... hier also nochmal kurz besagte Funktion mit einer übetragung der
> Idee von Karl Heinz... zumidnest so wie ich es verstanden habe.


Nein.
Das ist nicht das, was ich dir gezeigt habe.
Scroll noch einmal hoch und sieh es dir genau an!

Da gibt es einen Trick, denn du offenbar nicht geschnallt hast.

Ich habe eine Struktur.
Ich allokiere aber mehr Speicher als ich für die Struktur eigentlich 
brauchen würde. Dieser 'mehr Speicher' ist genau der entscheidende 
Punkt: Er ist so bemessen, dass die Daten dort reinpassen werden.

Bei der Allokierung geht es nur darum eine Speicherfläche zu bekommen, 
die groß genug für die Struktur UND die Daten ist. Die eigentlichen 
Daten hab ich gar nicht in der Struktur drinnen. Ich tu einfach so, als 
ob am Anfang der allokierten Speicherfläche ein entsprechendes 
Strukturobjekt liegen würde, befülle das mit den relevanten 
Strukturkennwerten und die eigentlichen Daten schreibe ich dank des 
Strukturaufbaus in der Speicherfläche mehr oder weniger direkt in den 
allokierten Speicher hinten an die Struktur-Daten drann. Im Speicher 
kann dann kein Mensch mehr unterscheiden, ob ich da eine Struktur mit 
"variablem Array" habe oder ob ich anders zu meinem Speicheraufbau 
gekommen bin. Am allerwenigsten kann das msgsend.

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> struct MSGBUF* msg = malloc( sizeof( struct MSGBUF) + textlen );

Hi Karl-Hein

ich habe deine Variante jetzt mal nahezu 1:1 übernommen. allerdings 
springt er bei mir bei der obigen Zelle mit der Fehlermeldung aus: 
"ungültige Umwandlung von >>void*<< in >>MSGBUF2*<<"

Was muß ich hier noch ändern?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LeDan schrieb:
> Karl heinz Buchegger schrieb:
>> struct MSGBUF* msg = malloc( sizeof( struct MSGBUF) + textlen );
>
> Hi Karl-Hein
>
> ich habe deine Variante jetzt mal nahezu 1:1 übernommen. allerdings
> springt er bei mir bei der obigen Zelle mit der Fehlermeldung aus:
> "ungültige Umwandlung von >>void*<< in >>MSGBUF2*<<"
>
> Was muß ich hier noch ändern?

Dann solltest du zuallererst einen C Compiler benutzen und keinen C++ 
Compiler :-)

In C ist ein void* zu allen anderen Datenpointern kompatibel (sprich 
kann zugewiesen werden). In C++ aber nicht.
struct MSGBUF* msg = (struct MSGBUF*) malloc( sizeof( struct MSGBUF) + textlen );

Autor: LeDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> struct MSGBUF* msg = (struct MSGBUF*) malloc( sizeof( struct MSGBUF) + textlen 
);

Hallo Karl Heinz und auch an alle anderen die hier geschrieben haben.

Ein riesengroßs dickes Dankeschön... Es funzt. Es werden Daten in 
variabler Länge über MSGSND übertragen.
Ich werd mir auf jeden Fall das Thema Shared Memory nochmal anschauen, 
aber das mache ich erst später. Jetzt werd ich erstmal alles etwas 
Dokumentieren und ich bin in meiner Diplomarbeit einen weiteren großen 
Schritt vorangekommen... also nochmal VIELEN VIELEN DANK für eure 
schnelle Hilfe. (Auch wenn ich manchmal ziemlich zu tun hatte dem 
Fachgesimpel zu folgen... aber es hatte sich am Ende gelohnt)

DANKE DANKE DANKE!!

von mir aus kann das Thema geschlossen werden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.