<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Von Klassen, Threads und FileIOCompletionRoutines ...]]></title><description><![CDATA[<p>Hallo.</p>
<p>Frage: Wie kann ich auf Membervariablen einer Klasse <em>ComPort</em> in einer</p>
<p>**VOID CALLBACK FileIOCompletionRoutine(DWORD errorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped)<br />
**</p>
<p>zugreifen?</p>
<p>Ich habe eine &quot;Dreiecksbeziehung&quot;:</p>
<p>1. Application<br />
2. Thread<br />
3. CompletionRoutine.</p>
<p>Alle drei Punkte müssen in einer Klasse definiert sein.</p>
<p>Waren 1. und 2. schon vorhanden, ist 3. echt hart!</p>
<p>Hier der Header für 1. und 2. (ohne Completion, funktioniert):</p>
<pre><code class="language-csharp">class ComPort
{
private:

	HANDLE					m_hCom;
	HANDLE					m_hReader, m_hWriter;	//threads
	COMMCONFIG				m_cc, m_ccBackup;
	COMMTIMEOUTS			m_cto, m_ctoBackup;
	DWORD					m_idReader, m_idWriter;
	DWORD					m_exitReader, m_exitWriter;
	volatile BOOL			m_runReader, m_runWriter;
	volatile LPVOID			m_bufferRead, m_bufferWrite;
	volatile ULONG			m_numRead, m_numWrite;

	static DWORD WINAPI		Reader(LPVOID parent);
	static DWORD WINAPI		Writer(LPVOID parent);

public:
	ComPort(void);
	BOOL				Open(VOID);
	BOOL				Close(VOID);
	BOOL				Write(LPVOID bufferWrite, USHORT *numWrite);
	BOOL				Read(LPVOID bufferRead, USHORT *numRead);
};
</code></pre>
<p>Alles mögliche habe ich schon</p>
<pre><code class="language-csharp">static
</code></pre>
<p>gemacht:</p>
<p>- Instanz der Klasse<br />
- die in der Completion-Routine benötigten Membervariablen<br />
- eine Woche gegoogelt ...</p>
<p>Langsam habe ich kein Bock mehr auf den Scheiss, aber <strong>diese</strong> Zeilen im ReaderThread können gewaltig nach hinten losgehen (z.B. Kabel ab während der Übertragung).</p>
<pre><code class="language-csharp">while (byteRead != 4) //Header vom Protokoll lesen, um PacketSize zu ermitteln
{
    GetOverlappedResult(com-&gt;m_hCom,&amp;ovl,&amp;byteRead,false);
}
</code></pre>
<p>Die Completion-Routine soll mir die StateMachine weiterschalten und auf Checksum prüfen.</p>
<p>Bin dankbar für jede <strong>konstruktive</strong> Antwort!</p>
<p>Gruss</p>
<p>Lars</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/227773/von-klassen-threads-und-fileiocompletionroutines</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 01:28:13 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/227773.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 19 Nov 2008 20:22:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Wed, 19 Nov 2008 20:22:28 GMT]]></title><description><![CDATA[<p>Hallo.</p>
<p>Frage: Wie kann ich auf Membervariablen einer Klasse <em>ComPort</em> in einer</p>
<p>**VOID CALLBACK FileIOCompletionRoutine(DWORD errorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped)<br />
**</p>
<p>zugreifen?</p>
<p>Ich habe eine &quot;Dreiecksbeziehung&quot;:</p>
<p>1. Application<br />
2. Thread<br />
3. CompletionRoutine.</p>
<p>Alle drei Punkte müssen in einer Klasse definiert sein.</p>
<p>Waren 1. und 2. schon vorhanden, ist 3. echt hart!</p>
<p>Hier der Header für 1. und 2. (ohne Completion, funktioniert):</p>
<pre><code class="language-csharp">class ComPort
{
private:

	HANDLE					m_hCom;
	HANDLE					m_hReader, m_hWriter;	//threads
	COMMCONFIG				m_cc, m_ccBackup;
	COMMTIMEOUTS			m_cto, m_ctoBackup;
	DWORD					m_idReader, m_idWriter;
	DWORD					m_exitReader, m_exitWriter;
	volatile BOOL			m_runReader, m_runWriter;
	volatile LPVOID			m_bufferRead, m_bufferWrite;
	volatile ULONG			m_numRead, m_numWrite;

	static DWORD WINAPI		Reader(LPVOID parent);
	static DWORD WINAPI		Writer(LPVOID parent);

public:
	ComPort(void);
	BOOL				Open(VOID);
	BOOL				Close(VOID);
	BOOL				Write(LPVOID bufferWrite, USHORT *numWrite);
	BOOL				Read(LPVOID bufferRead, USHORT *numRead);
};
</code></pre>
<p>Alles mögliche habe ich schon</p>
<pre><code class="language-csharp">static
</code></pre>
<p>gemacht:</p>
<p>- Instanz der Klasse<br />
- die in der Completion-Routine benötigten Membervariablen<br />
- eine Woche gegoogelt ...</p>
<p>Langsam habe ich kein Bock mehr auf den Scheiss, aber <strong>diese</strong> Zeilen im ReaderThread können gewaltig nach hinten losgehen (z.B. Kabel ab während der Übertragung).</p>
<pre><code class="language-csharp">while (byteRead != 4) //Header vom Protokoll lesen, um PacketSize zu ermitteln
{
    GetOverlappedResult(com-&gt;m_hCom,&amp;ovl,&amp;byteRead,false);
}
</code></pre>
<p>Die Completion-Routine soll mir die StateMachine weiterschalten und auf Checksum prüfen.</p>
<p>Bin dankbar für jede <strong>konstruktive</strong> Antwort!</p>
<p>Gruss</p>
<p>Lars</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1617366</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1617366</guid><dc:creator><![CDATA[chezzmatazz]]></dc:creator><pubDate>Wed, 19 Nov 2008 20:22:28 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Thu, 20 Nov 2008 08:18:19 GMT]]></title><description><![CDATA[<p>Du kannst alle OVERLAPPED Strukturen, die aktuell warten in eine klasseneigenen statisch Map verwalten. In der Map speicherst Du zusätzlich die Info welcher ComPort das war.</p>
<p>Dann kann die FileIOCompletionRoutine Routine in die Map hineinsehen und das Objekt finden, der diese Operation auslöste.</p>
<p>Es ist unsinnig alle Klassenmember statisch zu machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1617497</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1617497</guid><dc:creator><![CDATA[Martin Richter]]></dc:creator><pubDate>Thu, 20 Nov 2008 08:18:19 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Thu, 20 Nov 2008 19:43:16 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/35992">@Martin</a>: Danke, dass Du mir Denkanstösse gegeben hast!</p>
<p>C++ lernt man ein Leben lang!</p>
<p>Jetzt ist alles in einer Klasse: ThreadFunc und FileIOCompletionRoutine!</p>
<p>Der Header:</p>
<pre><code class="language-cpp">class ComPort
{
private:

	static HANDLE			m_hCom;
	HANDLE					m_hReader, m_hWriter;	//threads
	COMMCONFIG				m_cc, m_ccBackup;
	COMMTIMEOUTS			m_cto, m_ctoBackup;
	DWORD					m_idReader, m_idWriter;
	DWORD					m_exitReader, m_exitWriter;
	volatile BOOL			m_runReader, m_runWriter;
	volatile LPVOID			m_bufferRead, m_bufferWrite;
	volatile ULONG			m_numRead, m_numWrite;

	static DWORD WINAPI		Reader(LPVOID parent);
	static DWORD WINAPI		Writer(LPVOID parent);
	static VOID CALLBACK	CompletionReader(DWORD error,DWORD transfered,OVERLAPPED* ovl);
	static VOID CALLBACK	CompletionWriter(DWORD error,DWORD transfered,OVERLAPPED* ovl);

public:
	ComPort(void);
	BOOL				Open(VOID);
	BOOL				Close(VOID);
	BOOL				Write(LPVOID bufferWrite, USHORT *numWrite);
	BOOL				Read(LPVOID bufferRead, USHORT *numRead);
};
</code></pre>
<p>Im .cpp war es nur eine einzige Zeile direkt am Beginn!</p>
<pre><code class="language-cpp">#include &quot;this and that.h&quot;

//--------------------------------------------------------

HANDLE ComPort::m_hCom = INVALID_HANDLE_VALUE; //&lt;-Initialisierung einer statischen Member-Variablen!

//--------------------------------------------------------

/*!
    wie gehabt
*/
</code></pre>
<p>UND WIE DAS LÄUFT!</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/35992">@Martin</a>: Danke nochmal!!!</p>
<p>Gruss</p>
<p>Lars</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1617940</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1617940</guid><dc:creator><![CDATA[chezzmatazz]]></dc:creator><pubDate>Thu, 20 Nov 2008 19:43:16 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Thu, 20 Nov 2008 19:47:47 GMT]]></title><description><![CDATA[<p><strong>Starcraft</strong> zocken!</p>
<p>PS:</p>
<p>Ich habs! Wie geil ... !</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1617944</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1617944</guid><dc:creator><![CDATA[chezzmatazz]]></dc:creator><pubDate>Thu, 20 Nov 2008 19:47:47 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Thu, 20 Nov 2008 21:04:10 GMT]]></title><description><![CDATA[<p>@chezzmatazz: Das ist der grösste Mist den ich seit langem gesehen habe.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/35992">@Martin</a> Richter: ich mache das so dass ich ne eigene struct von OVERLAPPED ableite, und da drin dann einen Zeiger auf die &quot;outer&quot; Class speichere. Im Callback dann einfach per static_cast auf meine Struct zurückcasten, und über den &quot;outer&quot; Pointer kommt man dann an das Objekt dran. IMO viel eleganter und vor allem viel performanter als eine statische Map.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1617990</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1617990</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 20 Nov 2008 21:04:10 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Thu, 20 Nov 2008 21:25:14 GMT]]></title><description><![CDATA[<p>Für Besseres bin ich immer offen.</p>
<p>Aber ich versteh nicht, was Du meinst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1618000</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1618000</guid><dc:creator><![CDATA[chezzmatazz]]></dc:creator><pubDate>Thu, 20 Nov 2008 21:25:14 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Fri, 21 Nov 2008 21:51:55 GMT]]></title><description><![CDATA[<p>Erstmal wieso es IMO Mist ist: einfach deswegen, weil das eine static Member die ganze Klasse ad absurdum führt. Wenn du das Port Handle static machst kannst du nie mehr als eine Instanz der Klasse haben, zumindest nicht wenn die Instanzen unterschiedliche Ports verwenden sollen (und davon gehe ich mal aus). Wenn du nie mehr als eine Instanz der Klasse haben kannst, dann ist die Klasse für nix, dann könntest du genauso mit freien Funktionen + globalen Variablen (evtl. in einem Namespace) arbeiten.</p>
<p>Wie man es besser machen kann: verwende nicht einfach &quot;nackte&quot; OVERLAPPED structs, sondern eine struct die von OVERLAPPED abgeleitet ist. In diese struct packst du dann den &quot;this&quot; Zeiger rein. Beispiel:</p>
<pre><code class="language-cpp">class ComPort
{
    // ...

    HANDLE m_hCom;

    struct MyOverlapped : OVERLAPPED
    {
        MyOverlapped(ComPort* instance) : m_instance(instance) { }
        ComPort* m_instance;
    };

    static void CALLBACK StaticReadCompletionRoutine(DWORD error, DWORD transfered, OVERLAPPED* ovl)
    {
        MyOverlapped* myOvl = static_cast&lt;MyOverlapped*&gt;(ovl);
        myOvl-&gt;m_instance-&gt;ReadCompletionRoutine(error, transferred, ovl);
    }

    void ReadCompletionRoutine(DWORD error, DWORD transfered, OVERLAPPED* ovl)
    {
        // hier hast du jetzt deinen &quot;this&quot; Zeiger und kannst auf m_hCom zugreifen, ohne dass es static sein muss
    }
};
</code></pre>
<p>Damit das funktioniert musst du natürlich überall wo du ursprünglich eine OVERLAPPED struct verwendet hast jetzt eine MyOverlapped struct verwenden, die du mit dem &quot;this&quot; Zeiger des entsprechenden Objekts initialisierst. In den Fällen in denen ich bisher sowas gebraucht habe ist das allerdings kein Problem gewesen, da sämtliche Aufrufe von Funktionen die eine OVERLAPPED struct erwarten sowieso innerhalb der Klasse erfolgt sind der auch die completion routine gehört.</p>
<p>EDIT: Fehler korrigiert, die nicht-statische completion routine heisst natürlich &quot;ReadCompletionRoutine&quot;, nicht nochmal &quot;StaticReadCompletionRoutine&quot; <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1618062</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1618062</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 21 Nov 2008 21:51:55 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Fri, 21 Nov 2008 06:15:44 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/35992">@Martin</a> Richter: ich mache das so dass ich ne eigene struct von OVERLAPPED ableite, und da drin dann einen Zeiger auf die &quot;outer&quot; Class speichere. Im Callback dann einfach per static_cast auf meine Struct zurückcasten, und über den &quot;outer&quot; Pointer kommt man dann an das Objekt dran. IMO viel eleganter und vor allem viel performanter als eine statische Map.</p>
</blockquote>
<p>Jupp 100% korrekt!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1618084</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1618084</guid><dc:creator><![CDATA[Martin Richter]]></dc:creator><pubDate>Fri, 21 Nov 2008 06:15:44 GMT</pubDate></item><item><title><![CDATA[Reply to Von Klassen, Threads und FileIOCompletionRoutines ... on Fri, 21 Nov 2008 18:35:05 GMT]]></title><description><![CDATA[<p>Herzlichen Dank euch zweien für die Mühe!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1618526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1618526</guid><dc:creator><![CDATA[chezzmatazz]]></dc:creator><pubDate>Fri, 21 Nov 2008 18:35:05 GMT</pubDate></item></channel></rss>