<?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[Timer mit APC-Aufruf]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hab hier mal ein kleines Testprogramm geschrieben. Allerdings verstehe ich nicht, warum er nicht in <strong>TimerApc(...)</strong> springt, obwohl der Timer signalisiert wird.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;iomanip&gt;

using namespace std;

#include &quot;Windows.h&quot;
#include &quot;Time.h&quot;

#define NAME_TI &quot;Name_Ti_Test&quot;
HANDLE hTi_Test = NULL;

void PrintTime (char *pcLabel) //die Ausgabe von Zeitstempeln
{
  if (pcLabel == NULL)
    return;

  SYSTEMTIME sTime;
  GetSystemTime (&amp;sTime);

  cout &lt;&lt; endl &lt;&lt; endl &lt;&lt; pcLabel &lt;&lt; &quot;: &quot; 
    &lt;&lt; setw (2) &lt;&lt; setfill('0') 
    &lt;&lt; (sTime.wHour+1) &lt;&lt; &quot;:&quot;
    &lt;&lt; sTime.wMinute &lt;&lt; &quot;:&quot;
    &lt;&lt; sTime.wSecond &lt;&lt; &quot;,&quot;
    &lt;&lt; setw (3) &lt;&lt; setfill('0') 
    &lt;&lt; sTime.wMilliseconds;
  return;
}

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

void APIENTRY TimerApc (LPVOID, DWORD, DWORD) //&lt;- hier will er nicht reinspringen
{
  PrintTime (&quot;ENDE&quot;);
  return;
}

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

void ResetTimer(LARGE_INTEGER&amp; rliTime) //Timer mit dem neuen Wert starten
{
  if (hTi_Test != NULL)    
  {
    SetWaitableTimer (hTi_Test, &amp;rliTime, 0, 
        (PTIMERAPCROUTINE)TimerApc, NULL, false);
    PrintTime (&quot;START&quot;);
  }

  return;
}

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

int main (int argc, char **argv)
{
  hTi_Test = CreateWaitableTimer (NULL, false, NAME_TI);
  if (hTi_Test == NULL)
  {
    cout &lt;&lt; endl &lt;&lt; &quot;Erstellung des Timers fehlgeschlagen!&quot;;
    return -1;
  }

  SYSTEMTIME sTime;
  LARGE_INTEGER liTime;
  liTime.QuadPart = 1;

  while (liTime.QuadPart != 0)
  {
    memset (&amp;liTime, 0, sizeof(liTime));

    cout &lt;&lt; endl &lt;&lt; &quot;Timerlaenge angeben [in 100ns]: &quot;;
    cin &gt;&gt; liTime.QuadPart; //negative Werte eingeben

    if (liTime.QuadPart == 0)
      break;

    ResetTimer (liTime);
    if ((WaitForSingleObject (hTi_Test, 3000)) != WAIT_TIMEOUT)
      cout &lt;&lt; endl &lt;&lt; &quot;Timer signalisiert!&quot; &lt;&lt; endl;
  }

  CancelWaitableTimer (hTi_Test);
  CloseHandle (hTi_Test);
  return 0;
}
</code></pre>
<p>Sicher ich könnte auch einen Thread auf das Ablaufen des Timers warten lassen, aber die Lösung für mein Problem über den Apc-Aufruf, wäre wesentlich eleganter.<br />
Als Compiler benutze ich den, der von Borland bei der BCB6-Umgebung mitgeliefert wird. Ich weiss allerdings nicht, in wie weit das wichtig ist.</p>
<p>Hat jemand von euch damit Erfahrung?</p>
<p>Maffe</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/137081/timer-mit-apc-aufruf</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Jul 2026 20:38:58 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/137081.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 15 Feb 2006 10:18:25 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Timer mit APC-Aufruf on Wed, 15 Feb 2006 10:18:25 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hab hier mal ein kleines Testprogramm geschrieben. Allerdings verstehe ich nicht, warum er nicht in <strong>TimerApc(...)</strong> springt, obwohl der Timer signalisiert wird.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;iomanip&gt;

using namespace std;

#include &quot;Windows.h&quot;
#include &quot;Time.h&quot;

#define NAME_TI &quot;Name_Ti_Test&quot;
HANDLE hTi_Test = NULL;

void PrintTime (char *pcLabel) //die Ausgabe von Zeitstempeln
{
  if (pcLabel == NULL)
    return;

  SYSTEMTIME sTime;
  GetSystemTime (&amp;sTime);

  cout &lt;&lt; endl &lt;&lt; endl &lt;&lt; pcLabel &lt;&lt; &quot;: &quot; 
    &lt;&lt; setw (2) &lt;&lt; setfill('0') 
    &lt;&lt; (sTime.wHour+1) &lt;&lt; &quot;:&quot;
    &lt;&lt; sTime.wMinute &lt;&lt; &quot;:&quot;
    &lt;&lt; sTime.wSecond &lt;&lt; &quot;,&quot;
    &lt;&lt; setw (3) &lt;&lt; setfill('0') 
    &lt;&lt; sTime.wMilliseconds;
  return;
}

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

void APIENTRY TimerApc (LPVOID, DWORD, DWORD) //&lt;- hier will er nicht reinspringen
{
  PrintTime (&quot;ENDE&quot;);
  return;
}

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

void ResetTimer(LARGE_INTEGER&amp; rliTime) //Timer mit dem neuen Wert starten
{
  if (hTi_Test != NULL)    
  {
    SetWaitableTimer (hTi_Test, &amp;rliTime, 0, 
        (PTIMERAPCROUTINE)TimerApc, NULL, false);
    PrintTime (&quot;START&quot;);
  }

  return;
}

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

int main (int argc, char **argv)
{
  hTi_Test = CreateWaitableTimer (NULL, false, NAME_TI);
  if (hTi_Test == NULL)
  {
    cout &lt;&lt; endl &lt;&lt; &quot;Erstellung des Timers fehlgeschlagen!&quot;;
    return -1;
  }

  SYSTEMTIME sTime;
  LARGE_INTEGER liTime;
  liTime.QuadPart = 1;

  while (liTime.QuadPart != 0)
  {
    memset (&amp;liTime, 0, sizeof(liTime));

    cout &lt;&lt; endl &lt;&lt; &quot;Timerlaenge angeben [in 100ns]: &quot;;
    cin &gt;&gt; liTime.QuadPart; //negative Werte eingeben

    if (liTime.QuadPart == 0)
      break;

    ResetTimer (liTime);
    if ((WaitForSingleObject (hTi_Test, 3000)) != WAIT_TIMEOUT)
      cout &lt;&lt; endl &lt;&lt; &quot;Timer signalisiert!&quot; &lt;&lt; endl;
  }

  CancelWaitableTimer (hTi_Test);
  CloseHandle (hTi_Test);
  return 0;
}
</code></pre>
<p>Sicher ich könnte auch einen Thread auf das Ablaufen des Timers warten lassen, aber die Lösung für mein Problem über den Apc-Aufruf, wäre wesentlich eleganter.<br />
Als Compiler benutze ich den, der von Borland bei der BCB6-Umgebung mitgeliefert wird. Ich weiss allerdings nicht, in wie weit das wichtig ist.</p>
<p>Hat jemand von euch damit Erfahrung?</p>
<p>Maffe</p>
]]></description><link>https://www.c-plusplus.net/forum/post/994606</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/994606</guid><dc:creator><![CDATA[Maffe001]]></dc:creator><pubDate>Wed, 15 Feb 2006 10:18:25 GMT</pubDate></item><item><title><![CDATA[Reply to Timer mit APC-Aufruf on Wed, 15 Feb 2006 10:41:09 GMT]]></title><description><![CDATA[<p>WaitForSingleObjectEx ist die benötigte Funktion. WaitForSingleObject (ohne ex) wartet nicht auf APC.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/994638</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/994638</guid><dc:creator><![CDATA[mgs_]]></dc:creator><pubDate>Wed, 15 Feb 2006 10:41:09 GMT</pubDate></item><item><title><![CDATA[Reply to Timer mit APC-Aufruf on Wed, 15 Feb 2006 10:42:22 GMT]]></title><description><![CDATA[<p>Ich würde mal vemuten, weil Du versuchst, eine Windows-API in einem Consolenprogramm zu verwenden. APIENTRY ist ein Format, das für Windows-Programme genutzt wird, Deine &quot;int main&quot; ist aber nur ein DOS-Format.<br />
TimerApc erwartet drei Parameter (LPVOID, DWORD, DWORD), die Du beim aufruf nicht übergibst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/994641</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/994641</guid><dc:creator><![CDATA[Elektronix]]></dc:creator><pubDate>Wed, 15 Feb 2006 10:42:22 GMT</pubDate></item><item><title><![CDATA[Reply to Timer mit APC-Aufruf on Wed, 15 Feb 2006 10:58:19 GMT]]></title><description><![CDATA[<p><strong>@mgs_:</strong><br />
Ich hab das Ganze schon auf WaitForSingleObjectEx geändert. Funktioniert trotzdem nicht.</p>
<p><strong>@Electronix:</strong><br />
Ich brauch ja auch nicht unbedingt, was übergeben, bei einem solch &quot;einfachen&quot; Aufruf. Das mit dem DOS ist ein Argument. Müsste dann nicht aber der Compiler sich beschweren? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/994657</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/994657</guid><dc:creator><![CDATA[Maffe001]]></dc:creator><pubDate>Wed, 15 Feb 2006 10:58:19 GMT</pubDate></item><item><title><![CDATA[Reply to Timer mit APC-Aufruf on Wed, 15 Feb 2006 11:16:04 GMT]]></title><description><![CDATA[<p>Ich hab's jetzt so geändert. Und so funktionierts.</p>
<pre><code class="language-cpp">int main (int argc, char **argv)
{
  hTi_Test = CreateWaitableTimer (NULL, false, NAME_TI);
  if (hTi_Test == NULL)
  {
    cout &lt;&lt; endl &lt;&lt; &quot;Erstellung des Timers fehlgeschlagen!&quot;;
    return -1;
  }

  SYSTEMTIME sTime;
  LARGE_INTEGER liTime;
  liTime.QuadPart = 1;

  while (liTime.QuadPart != 0)
  {
    memset (&amp;liTime, 0, sizeof(liTime));

    cout &lt;&lt; endl &lt;&lt; &quot;Timerlaenge angeben [in 100ns]: &quot;;
    cin &gt;&gt; liTime.QuadPart;

    if (liTime.QuadPart == 0)
      break;

    ResetTimer (liTime);

    if ((SleepEx (3000, true)) == 0)
      cout &lt;&lt; endl &lt;&lt; endl &lt;&lt; &quot;Timer noch nicht abgelaufen!&quot; &lt;&lt; endl;
    else
      cout &lt;&lt; endl &lt;&lt; endl &lt;&lt; &quot;APC-Aufruf!&quot; &lt;&lt; endl;
  }

  CancelWaitableTimer (hTi_Test);
  CloseHandle (hTi_Test);
  return 0;
}
</code></pre>
<p>Der Grund war:</p>
<p>Jeffrey Richter - Microsoft Windows, Programmierung für Experten schrieb:</p>
<blockquote>
<p>HANDLE hTimer = CreateWaitableTimer (....);<br />
SetWaitableTimer (hTimer, ..., TimerAPCRoutine, ...);<br />
WaitForSingleObjectEx (hTimer, INFINITE, true);</p>
<p>Derartiger Code ist zu vermeiden, da der Aufruf von WaitForSingleObjectEx in Wirklichkeit ein zweifaches Warten impliziert, einmal per Alarmierung und zum zweiten über ein Handle für ein Kernel-Objekt. Wenn der Zeitgeber in den signalisierten Zustand wechselt, war das Warten erfolgreich und der Thread wird aktiviert. Letzteres bewirkt ein Verlassen des alarmierbaren Zustands, weshalb die APC-Prozedur nicht aufgerufen wird. [...]</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/994676</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/994676</guid><dc:creator><![CDATA[Maffe001]]></dc:creator><pubDate>Wed, 15 Feb 2006 11:16:04 GMT</pubDate></item></channel></rss>