Forum: PC-Programmierung Windows CE Interprozess Kommunikation


von Josef (Gast)


Lesenswert?

Hallo zusammen,

ich brauche ein kleinbisschen Starthilfe.
Bei Linux habe ich mich schon etwas mit dem Thema 
Interprozesskommunikation beschäftigt, also mit Sockets, MessageQueues, 
Semaphoren etc.

Nun möchte ich aber unter Windows CE 2 Programme miteinander 
Kommunizieren lassen. Das eine Programm arbeitet mit der Seriellen 
Schnittstelle und das andere verarbeitet diese Daten.

Kann mir jemand ein klein bisschen Starthilfe geben wie ich das am 
besten angehe?

Ich hatte erst an Messagequeues gedacht. Dabei habe ich aber gesehen, 
dass OpenMsgQueue den Prozesshandle und den Handle der erstellten 
MsgQueue haben möchte. Diese kann ich doch garnicht liefern, oder etwar 
doch? Meine Kenntnisse von Windows CE sind noch sehr beschränkt, 
deswegen fehlt mir ein bisschen der Überblick.

Ich hoffe ihr könnt mir ein bisschen bei den Startschwierigkeiten helfen 
und mir eine Kommunikationsart Empfehlen.

Gruß
Josef

P.S.: Bei der Geschichte mit Sockets über den Localhost, gibt das 
Probleme mit Firewalls?

von Purzel H. (hacky)


Lesenswert?

Probier das Ganze mit einem Debugger doch schnell aus.

Eine Firewall sollte nur gegen Aussen wirken.

von Josef (Gast)


Lesenswert?

ich hab das Windows CE Gerät momentan nicht da aber du hast recht, die 
Firewall geschichte könnte ich auch in der Debug Simulation starten.

Habe ich denn recht das es mit Messagequeues nicht geht sondern bei so 
einer Prozesskommunikation nur noch die Sockets bleiben? Oder gibt es 
eine alternative und welche Vor-/Nachteile hat dies?

Bei der Überlegung des Problems kamen mir auch noch ein paar Fragen.

Wo werden Globale Variablen gespeichert? Auch wenn sie Global heißen 
sind sie doch nur für die Prozesse verfügbar und ein anderes .exe 
Programm kann nicht auf die Globalenvariablen eines anderen Zugreifen, 
oder?

von Peter (Gast)


Lesenswert?

warum müssen es denn 2 Prozesse sein? Durch das IPC ist das ganze doch 
viel komplexer.

Unter windows könnte man das ganze aber über die normale Messageque 
machen. Sonst gibt es auch noch Shared Memory und eventuell kommt auch 
eine Pipe in frage.

Die Pipe würde sich vermutlich am einfachsten machen, weiss aber nicht 
ob sie in WindowsCE vorhanden ist.

von Josef (Gast)


Lesenswert?

Es müssen 2 Programme werden weil sich ein Programm mit der 
Datenbeschaffung und das andere mit der Verarbeitung befasst. Das 
Programm der Datenbeschaffung kann sich später auch ändern bzw. wird 
durch ein anderes ersetzt.

Du sagst das in Windows dies über normale Messageques machbar ist. 
Meinst du damit die Taskkommunikation oder wirklich die Kommunikation 
zwischen 2 Prozessen/Programmen. Wenn ja, wie geht dies?

von Peter (Gast)


Lesenswert?

Josef schrieb:
> Es müssen 2 Programme werden weil sich ein Programm mit der
> Datenbeschaffung und das andere mit der Verarbeitung befasst. Das
> Programm der Datenbeschaffung kann sich später auch ändern bzw. wird
> durch ein anderes ersetzt.

was ist denn das für ein Grund?

1. ein programm kann auch mehrere Dinge gleichzeitig machen
   (z.b. mit Threads)
2. Ist doch egal ob du nun das eine Programm austauschst oder nicht, 
warum
   sollte dann der Teil mit der Varbeitung nicht mit ausgetauscht 
werden?

dafür hättest du ein Programm was wesentlich besser zur Testen ist. 
Sonst passiert es dir früher oder später das beide Programm nicht 
zusammenpassen weil du etwas am Datenaustausch geändert hast.

Im Windows gibt es noch ein globale Message, darüber erfolgt z.b. die 
Benachrichtung wenn z.b. Windows in den Schlafmodus wechseln will, in 
diesen kann man auch Daten austauschen. Ob das sinnvoll ist hängt aber 
von der Menge und häufigkeit der Daten ab.

von Josef (Gast)


Lesenswert?

Ich möchte dies aber in 2 Programmen machen, da sich 1. später jemand 
anderes mit dem einen Teil beschäftigen soll und 2. ich später wirklich 
nur ein Programm anpassen/austauschen möchte ohne das andere anzupassen.

Klar das die Schnittstelle für den Datenaustausch fest geregelt sein 
muss damit es zu keinen Problemen führt.

Die Geschichte mit den globalen Messages klingt nicht Sinnvoll. Es 
werden sicher im sekunden Takt um die 256 Bytes abgefragt. Anscheinend 
könnte es am besten per Socketverbindung passieren. Oder einer 
"virtuellen Datei" aber da weiß ich noch nicht wie ich eine Dateianlege 
die nicht aufs Flashlaufwerk geschrieben werden soll sondern nur im RAM 
zur Verfügung steht.

In welcher Weise könnte man denn das ganze als DLL nutzen? Bei der DLL 
müsste ich dann eine Funktion für den Datenaustausch implementieren und 
das eine Programm ruft diese Funktion dann auf? Eventuell wäre das noch 
eine alternative. Dabei müsste ich aber noch eine Initfunktion 
erstellen, die in dem zweiten Programm immer aufgerufen wird.

von Josef (Gast)


Lesenswert?

Nachtrag:
DLL's sind auch kein Problem wenn die DLL in C/C++ geschrieben wird und 
das andere Programm in .net VB?

von Zwie B. (zwieblum)


Lesenswert?

@Peter: "Teile und herrsche". Weil das unter Windows sooo schwierig ist, 
sind die Programme ja auch solche Wasserköpfe.

von Peter (Gast)


Lesenswert?

Zwie Blum schrieb:
> @Peter: "Teile und herrsche". Weil das unter Windows sooo schwierig ist,
> sind die Programme ja auch solche Wasserköpfe.

ja aber wenn der code für eine Seriellen Schnittstelle kleiner ist, also 
der code für IPC dann fragt man sich schon nach dem sinn.
Dazu kommen dann noch solche Probleme wie, wer startet denn das 
2.Programm? wer beendet es wieder. Was passiert wenn das 
auswerteprogramm zwei mal gestartet wird?
sinvollerweise müsste man den seriellen Teil in einen Dienst auslagern 
der vom System gestartet wird. (keine ahnung ob das bei CE auch geht).

@Josef
Aber eine DLL ist hat erstmal wenig mit IPC zu tun. Wenn du es mit einer 
DLL machen willst dann geht es auch ohne IPC. eine C (nicht C++) dll 
kannst du ohne PRobleme von .net ansprechen.

von Zwie B. (zwieblum)


Lesenswert?

Also wenn windows nicht mal verläßlich Programme starten kann ... 
hüstel

von Josef (Gast)


Lesenswert?

vielen dank für eure diskussionsbeiträge.

Das die ganzen Fehler abgefangen werden müssen ist mir schon klar und 
ist auch ein großer Aufwand, trotzdem soll der Teil ausgelagert werden.

Meine Frage bezüglich der DLL Geschichte ist noch: Kann ich die DLL auf 
dem Gerät tauschen und mit einer neuen DLL die z.B. dann über TCP/IP 
arbeitet ersetzen und das Programm läuft weiter? Also wird die DLL zur 
Laufzeit eingebunden oder beim Kompilieren?

Beide Programme werden im Autostart gestartet, das sollte Windows CE 
doch noch schaffen....hoffentlich.

Das Programm, welches im moment die Serielle Schnittstelle bedient muss 
später auch Realtimefähig sein. Das andere Programm wird in .net 
Programmiert und ist somit schon nicht mehr Echtzeitfähig. Das ist auch 
ein Grund, weswegen es 2 Programme sein müssen.

Einfacher für das spätere Handling wird somit eine IPC anstatt die DLL 
Variante.

von Peter (Gast)


Lesenswert?

Josef schrieb:
> Meine Frage bezüglich der DLL Geschichte ist noch: Kann ich die DLL auf
> dem Gerät tauschen und mit einer neuen DLL die z.B. dann über TCP/IP
> arbeitet ersetzen und das Programm läuft weiter? Also wird die DLL zur
> Laufzeit eingebunden oder beim Kompilieren?
das kannst du machen wie du willst. Aber wenn du sie zur laufzeit 
tauschen willst dann musst du im program die möglichkeit vorsehen die 
dll zu entladen. Ob es aus .net geht weiss ich nicht. Windows bietet es 
aber grundsätzlich an.

> Das Programm, welches im moment die Serielle Schnittstelle bedient muss
> später auch Realtimefähig sein.
nur mal aus neugier - warum?
Geht es dir nur darum um keine Daten zu verlieren oder müssen die daten 
in einer gewissen zeit angenommen und bestätigt werden?

von Josef (Gast)


Lesenswert?

ok. die dll geschichte klingt doch nicht so simpel wie gedacht. ich 
hätte erwartet das ich sie 1:1 an die Stelle kopiere und alles gut ist.

Das Programm welches die Serielle Schnittstelle bedient wird später 
durch ein Programm ersetzt welches Echtzeitfähig arbeiten muss. Es 
werden dort Programme mit genauem Zeitverhalten abgearbeitet. Bei der 
Seriellenschnittstelle lassen sich auch Timeouts definieren, diese 
müssen auch exakt arbeiten. Ich weiß nicht 100% ob sie das bei .net 
tuen. Ich weiß zwar auch nicht ob sie das in C/C++ machen aber dort gehe 
ich einfach davon aus.

von Karl H. (kbuchegg)


Lesenswert?

Josef schrieb:
> ok. die dll geschichte klingt doch nicht so simpel wie gedacht. ich
> hätte erwartet das ich sie 1:1 an die Stelle kopiere und alles gut ist.

Das kann so ablaufen. Ja.

> Das Programm welches die Serielle Schnittstelle bedient wird später
> durch ein Programm ersetzt welches Echtzeitfähig arbeiten muss.

definiere was 'echtzeitfähig' für dich bedeutet.

Dir ist hoffentlich auch klar, dass die Fähigkeit 'echtzeitfähig' 
abzulaufen hauptsächlich vom zugrundeliegenden Betriebssystem abhängt?
Wenn Windows seinen Plattencache aufräumt, dann räumt es den auf. Andere 
Prozesse haben dann Pause, wenn Windows es will.

von Peter (Gast)


Lesenswert?

Josef schrieb:
> Es
> werden dort Programme mit genauem Zeitverhalten abgearbeitet. Bei der
> Seriellenschnittstelle lassen sich auch Timeouts definieren, diese
> müssen auch exakt arbeiten.

wenn du sich bei der Schnittelle einrichtest dann ist es egal ob du es 
von .net oder c++ machst, es wird jeweil dem Betriebssystem übergeben. 
Um welche genaue zeitverhalten geht es denn? Millisekunden, Sekunden? 
.net ist erstmal nicht wirklich langsamer als mit c geschrieben 
programme. Und wenn es wirklich nur um ein paar byte gehen die von der 
Schnittstelle kommen wird es kein unterschied machen.
Meist sind sogar schlecht geschriebene C++ Programme langsamer als 
welche in C#, weil viele gar nicht bewusst ist das Objekte kopiert 
werden.

von Josef (Gast)


Lesenswert?

Es geht dabei um Millisekunden. Betriebssystem ist Windows CE 6.0 R2.

Windows garantiert ein 1ms Taskzyklus mit einem Glitch von max. ca. 
100µs. Bei .net Programmen räumt Windows zwischendurch den Cache auf und 
zerstört damit die Echtzeit, bei C/C++ Programmen ist dies aber nicht 
der Fall und bleibt weiterhin im 1ms Takt.

Die größe der Datenmenge wird sich im Bereich von 256Bytes abspielen, 
also nicht wenig aber auch keine riesen Mengen.

Das Echzeitfähigeprogramm muss später mit genauen Taskzeiten arbeiten 
und da darf es keine Toleranz von mehren ms geben. Einzelne Tasks werden 
mit 10ms oder 100ms arbeiten.

"Meist sind sogar schlecht geschriebene C++ Programme langsamer als
welche in C#..." gibt es da auch mehr Informationen drüber? Was zeichnet 
denn ein schlecht geschriebenes C++ Programm aus? Gibt es 
Funktionen/Algorithmen/Methoden/Arbeitsweisen die man defintiv vermeiden 
sollte?

von Peter (Gast)


Lesenswert?

Josef schrieb:
> gibt es da auch mehr Informationen drüber? Was zeichnet
> denn ein schlecht geschriebenes C++ Programm aus? Gibt es
> Funktionen/Algorithmen/Methoden/Arbeitsweisen die man defintiv vermeiden
> sollte?

class data
{
   char p[100];
};

langsam
void test1( const data d ) { /* mach was mit d /* };


schneller
void test2( const data& d ) { /* mach was /* };


das sind halt die Feinheiten.

Ich war auch immer der Meinung das Java/#c langsam ist, aber nach ein 
paar Tests hat sich gezeigt das kaum Anwendungen gibt wo man es 
wirklicht merkt. Meist kommt die langsamkeit nicht von der Sprache 
sondern sondern von einer falschen/ungünstigen Umsetzung der Aufgabe.

von Josef (Gast)


Lesenswert?

Also der Aufruf per Namensreferenz ist schneller als ein direkter 
zugriff auf eine variable/klasse?

gibts dafür eine sinnvolle erklärung? kann der compilier referenzen 
sinnvoll zwischenspeichern und bei wenigen somit schneller arbeiten und 
bei mehreren macht es kein unterschied mehr?

von Zwie B. (zwieblum)


Lesenswert?

Das kommt auf deinen Compiler an, welche Optimierung du verwendest etc. 
etc.

von Karl H. (kbuchegg)


Lesenswert?

Josef schrieb:
> Also der Aufruf per Namensreferenz ist schneller als ein direkter
> zugriff auf eine variable/klasse?
>
> gibts dafür eine sinnvolle erklärung?

Es muss beim Aufruf keine Kopie des Arguments gemacht werden.
Reicht das?

Entscheidungsbaum für Argumenttypen
1
           Ja                                        Nein
2
          +-----  Will die Funktion eine Variable  --------+
3
          |        beim Aufrufer ändern können?            |
4
          |                                                |
5
          v                                                |
6
 Ja  Gibt es den Fall, dass der     Nein                   |
7
+--  Aufrufer keine Variable hat?  -----+                  |
8
|                                       |                  |
9
|                                       |                  |
10
v                                       v                  |
11
Verwende einen Pointer       Verwende eine Referenz        |
12
                                                           |
13
                                                           |
14
                                +--------------------------+
15
                                |
16
            Ja                  v
17
       +-------------   Handelt es sich um einen    -----------+
18
       |                eingebauten skalaren Datentyp?         |
19
       |                (char, int, long, double, etc)         |
20
       |                                                       |
21
       v                                                       v
22
  Verwende pass per value                 Verwende eine const Referenz
23
  (Kopie übergeben)

von Thomas B. (escamoteur)


Lesenswert?

Also:

Ich denke die Dll mit einem eigenen Task dürfte für Dich das richtige 
sein.

1. Dll (DYNAMIC Link Library) werden immer zur Laufzeit geladen (nur 
wenn Du Sie bei laufendem Programm austauschen willst wirds etwas 
komplizierter)

2. Wenn Du kurze reaktionszeiten haben willst, dann gib dem task in der 
dll einen höhere priorität als einem normalen Task

http://msdn.microsoft.com/en-us/library/bb202728.aspx

Dann kommen Dir höchsten noch Treiber und das OS in die Quere aber nicht 
Dein .net Thread.

Gruß
Tom

von Josef (Gast)


Lesenswert?

ahja klar. die namensreferenz ist ja wie ein pointer auf die variable 
und somit erstellt er die variable nicht neu sondern kann direkt 
reinschreiben.
ich bin kein großer freund von diesen referenzen weil mir genau die 
information fehlt, dass ich direkt immer in der gleichen variable 
arbeite.

somit ist das oben aufgeführte beispiel doch auch eine komplett andere 
sache. in dem einen programm arbeite ich mit der beim aufruf erstellten 
kopie der variable und in der anderen arbeite ich in der aktuellen 
variable die sich auch zur laufzeit (bei mehreren tasks) ändern könnte.

also bei der referenz geschichte muss man auch gut aufpassen was man 
macht.

Verhindert das const beim Funktionsparameter das die Funktion die 
Variable beschreiben kann? Aber es verhindert nicht, dass die Variable 
in einer anderen Task manipuliert wird, oder?

von Thomas B. (escamoteur)


Lesenswert?

3. Wenns unbedingt zwei Processe sein müssen, dann nimm Sockets mit dem 
localhost (nein kein Problem mit Firewall, die gibts bei CE 
standardmäßig eh nicht) oder

4. Wenn Du eine message queue nehmen willst, nimm CreateMsgQueue da 
brauchst Du keine Handles:

http://msdn.microsoft.com/en-us/library/bb202792.aspx


Gruß
Tom

von Karl H. (kbuchegg)


Lesenswert?

Josef schrieb:

> also bei der referenz geschichte muss man auch gut aufpassen was man
> macht.

nicht wirklich.
Du musst nur const korrekt arbeiten. Das ist dann schon fast alles. 
Dafür kriegst du dann aber auch etwas: Du versetzt den Compiler in die 
Lage, dich in noch stärkerem Umfang vor dir selber zu schützen.

Und, oh ja.
Multitasking ist dann sowieso wieder eine eigene Sache. Das hat aber 
wieder weniger mit Referenzen zu tun, als viel mehr der Anwendung von 
Synchronisierungsmechanismen wie Semaphoren etc.

von Thomas B. (escamoteur)


Lesenswert?

Hört sich so an, als ob Du bisher noch nicht viel mit C/C++ gemacht 
hast, sonst wären Pointer/Referenzen was völlig normales.

Wenn Du Dih mit const nichts auskennst, dann würde ich es erst mal 
weglassen. Wenn man es nämlich nicht ganz konsequent im ganzen Programm 
macht kommt man schnell in teufels küche und fängt an das const 
wegzucasten.

Zur windows Processen/Taks etc kann ich Dir das hier noch empfehlen:

http://www.amazon.de/Programming-Applications-Microsoft-Windows/dp/1572319968/ref=sr_1_20?ie=UTF8&s=books-intl-de&qid=1276070066&sr=1-20

Ist zwar nicht speziell für CE aber funktioniert dor meist ebenso.

von Josef (Gast)


Lesenswert?

Vielen Dank für eure ganzen Tips.

Ich hab mir dieses Buch bestellte: 
http://www.amazon.de/Programming-Windows%C2%AE-Developer-Reference-PRO-Developer/dp/0735624178/ref=sr_1_1?ie=UTF8&s=books-intl-de&qid=1276070917&sr=8-1

Dauert aber noch bis es ankommt.

Ich habe vorher nut mit Pointer gearbeitet und nicht mit Referenzen.

CreateMsgQueue gibt mir jeweils den gleichen Handler zurück wenn ich den 
gleichen Namen in 2 Programmen aufrufe? Das wäre ja klasse.

So wie es aussieht wirds nun die Socketverbindung. Im moment mit einer 
Localenverbidnung und später könnte diese Leicht durch eine externe 
socket verbindung ersetzt werden. Diese Variante klang auch sehr 
interessant. Wobei mich bei der Socketverbindung der Overhead etwas 
stört.

Sachen wie Semaphoren/Mutex und andere Spermechanismen sind mir schon 
ein Begriff und habe ich in kleineren Programmen auf einem Unixsystem 
genutzt, doch die Windowswelt ist neu für mich.

von Thomas B. (escamoteur)


Lesenswert?

Josef schrieb:
> CreateMsgQueue gibt mir jeweils den gleichen Handler zurück wenn ich den
> gleichen Namen in 2 Programmen aufrufe? Das wäre ja klasse.

Exakt, wie sonst soll das andere Programm wissen wie es auf die Queue 
zugreifen kann?

Aber noch mal, ich sehe auch keinen Grund wieso Du nicht ne DLL nimmst. 
Mach dort nen eigenen Task mit höherer Priorität auf und gut is.

Ich selbst verwende Referenzen eigentlich kaum sondern meist Pointer, da 
damit auch beim Aufruf immer klar ist, ob per reference oder value 
übergeben wird.
Tom

P.S.: Handle, nicht Handler

von Karl H. (kbuchegg)


Lesenswert?

Josef schrieb:

> Ich habe vorher nut mit Pointer gearbeitet und nicht mit Referenzen.

Das ist das C Erbe.
In C++ wird wesentlich mehr mit Referenzen gemacht als mit Pointern.

Pointer übergibt man nur dann
* wenn es nicht anders geht, weil zb eine Funktion aus einer Lib
  aufgerufen werden soll und die nun mal einen Pointer haben will
* wenn die Funktion ausdrücken will
  Eigentlich erwarte ich vom Aufrufer eine Speicherfläche an der
  ich meine Ergüsse ablegen kann. Ich gebe aber dem Aufrufer die
  Möglichkeit, das auszuschlagen indem er mir einen NULL Pointer
  übergeben darf. In dem Fall tu ich dann nichts.

Ansonsten nimmt man Referenzen.
Und nein. Eine Referenz ist nicht per se ein 'versteckter Pointer'. Eine 
Referenz ist erst mal nur 'ein anderer Name für eine ansonsten 
existierende Variable'. Das hat so zunächst mal nichts mit Pointern zu 
tun, auch wenn der Compiler in manchen Fällen Referenzen mittels 
Pointern implementiert.

> interessant. Wobei mich bei der Socketverbindung der Overhead etwas
> stört.

Von nichts kommt nichts.
Entweder du willst die Flexibilität, die Verbindung auch über Kontinente 
hinweg herstellen zu können, oder du willst sie nicht.

Aber ist ja kein Problem, ist ja schliesslich C++
Da gibt es dann eine Basisklasse, die für den Rest des Programms ein 
Interface beschreibt, welches völlig losgelöst von irgendwelcher 
Technologie den Kommunikationsendpunkt beschreibt.
Und davon abgeleitet gibt es dann zb eine Klasse, die die eigentliche 
Kommunikation über TCP/IP implementiert oder eine andere Klasse, die 
dasselbe mittels Queues macht oder eine 3te, die das über Shared Memory 
erledigt, etc ....

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.