title: Python callback ctypes function with va_list
body: <p>I have a problem defining a callback function used by a dll to get the log of other functions of the dll.
  Here are the c function:</p>
  
  <pre><code>typedef void (RTMP_LogCallback)(int level, const char *fmt, va_list);
  void RTMP_LogPrintf(const char *format, ...);
  </code></pre>
  
  <p>Here is my python code:</p>
  
  <pre><code>dll = cdll.LoadLibrary('bin/librtmp.dll')
  CMPFUNC = CFUNCTYPE(c_int, c_int, c_char_p, c_void_p)
  def logCallBack(level, message, va_list):
      dll.RTMP_LogPrintf(message, va_list)
      return 0
  </code></pre>
  
  <p>The problem is that the log is dirty and unreadable:</p>
  
  <pre><code>    Parsed host    : ☺Parsed app     : ☺connect to stream
  ÄßGj♫¨', ... connected, handshaking?ßGj♥: Type Answer   : 27DBEC?ßGjä?┼♣: Server Uptime : 2612204?ßGj♥: FMS Version   : 2612204.2612100.488283845.4882
  83530?ßGj♥: Handshaking finished....ÄßGj♫¨', handshaked│°Gj♀☻: fd=2614284, size=2614180Invoking ▒?'ä°Gj♀☻: fd=2618556`÷Gjá%&amp;: server BW = 2618572ä°Gj♀
  ☻: fd=2618556o÷Gjá%&amp;: client BW = 2618572 2618468ä°Gj♀☻: fd=2618556?÷Gj, received ctrl. type: 2618572, len: 2618468?÷Gj, Stream Begin 2618572ä°Gj♀☻: f
  d=26185568÷Gj, received: chunk size change to 2618572ä°Gj♀☻: fd=2618556N÷Gj♣☺, received: invoke 2618572 bytes(object begin)Property: &lt;|±'☺&gt;Property: &lt;
  |±'☺&gt;Property: &lt;|±'OBJECT&gt;(object begin)Property: &lt;,´'☺&gt;Property: &lt;,´'☺&gt;Property: &lt;,´'☺&gt;(object end)Property: &lt;|±'OBJECT&gt;(object begin)Property: &lt;,´'☺
  &gt;Property: &lt;,´'☺&gt;Property: &lt;,´'☺&gt;Property: &lt;,´'OBJECT&gt;(object begin)Property: &lt;▄ý'☺&gt;(object end)Property: &lt;,´'☺&gt;Property: &lt;,´'☺&gt;(object end)(object en
  d)~÷Gjmt;, server invoking &lt;☺&gt;~÷Gj, received result for method call &lt;☺&gt;│°Gj♀☻: fd=2616844, size=2616740sending ctrl. type: 0x27f264│°Gj♀☻: fd=2616828,
   size=2616724│°Gj♀☻: fd=2616828, size=2616724Invoking ?‗'UsherToken: ú?B☻,☺│°Gj♀☻: fd=2617164, size=2617060Invoking )¶'ä°Gj♀☻: fd=2618556N÷Gj↔, receiv
  ed: invoke 2618572 bytes(object begin)Property: &lt;|±'☺&gt;Property: &lt;|±'☺&gt;Property: NULLProperty: &lt;|±'☺&gt;(object end)~÷Gj?⌂;, server invoking &lt;☺&gt;~÷Gj8¶;, r
  eceived result for method call &lt;☺&gt;¶÷Gj, seekTime=2617308, stopTime=2617204, sending play: â─↑?♥â╚*?e¶╔├U?ýâý►SVW?¨?w►?E*ëE??F♦┴Ó☻?┌??↨│°Gj♀☻: fd=26171
  64, size=2617060Invoking )¶'sending ctrl. type: 0x27f264│°Gj♀☻: fd=2616828, size=2616724ä°Gj♀☻: fd=2618556N÷Gj%, received: invoke 2618572 bytes(object
   begin)Property: &lt;|±'☺&gt;Property: &lt;|±'☺&gt;Property: NULLProperty: &lt;|±'☺&gt;(object end)~÷Gj?⌂;, server invoking &lt;☺&gt;~÷Gj, received result id 2617308 without
  matching requestä°Gj♀☻: fd=2618556?÷Gj, received ctrl. type: 2618572, len: 2618468?÷Gj☺, Stream Begin 2618572ä°Gj♀☻: fd=2618556N÷Gjö, received: invoke
   2618572 bytes(object begin)Property: &lt;|±'☺&gt;Property: &lt;|±'☺&gt;Property: NULLProperty: &lt;|±'OBJECT&gt;(object begin)Property: &lt;,´'☺&gt;Property: &lt;,´'☺&gt;Property:
   &lt;,´'☺&gt;Property: &lt;,´'☺&gt;(object end)(object end)~÷Gj?t;, server invoking &lt;☺&gt;~÷Gj┴t;, onStatus: ☺ä°Gj♀☻: fd=2618556N÷Gj?, received: invoke 2618572 bytes
  (object begin)Property: &lt;|±'☺&gt;Property: &lt;|±'☺&gt;Property: NULLProperty: &lt;|±'OBJECT&gt;(object begin)Property: &lt;,´'☺&gt;Property: &lt;,´'☺&gt;Property: &lt;,´'☺&gt;Propert, ...etc
  </code></pre>
  
  <p>I also tried to print directly message like this:</p>
  
  <pre><code>def logCallBack(level, message, va_list):
      print message
      return 0
  </code></pre>
  
  <p>but this time, log are incomplete:</p>
  
  <pre><code>%s, ... connected, handshaking
  %s: Type Answer   : %02X
  %s: Server Uptime : %d
  %s: FMS Version   : %d.%d.%d.%d
  %s: Handshaking finished....
  %s, handshaked
  %s: fd=%d, size=%d
  Invoking %s
  %s: fd=%d
  %s: server BW = %d
  %s: fd=%d
  %s: client BW = %d %d
  %s: fd=%d
  %s, received ctrl. type: %d, len: %d
  ... etc
  </code></pre>
  
  <p>Does anyone knows ho to fix this problem?</p>
  
  <p>Thanks in advance.</p>
  
  <p>Regards, Gontran</p>
  
  <p><strong>EDIT :</strong></p>
  
  <p>according to this thread (<a href="http://www.digipedia.pl/usenet/thread/15901/197/" rel="nofollow">http://www.digipedia.pl/usenet/thread/15901/197/</a>), ctypes doesn't provide a way of dealing with varargs functions. I get this point. But why using the RTMP_LogPrintf() function doesn't work correctly? I've the impression that I'm passing to the right arguments.</p>
  
  <p>For information, RTMP_LogPrintf() is defined like this:</p>
  
  <pre><code>void RTMP_LogPrintf(const char *format, ...)
  {
      char str[MAX_PRINT_LEN]="";
      int len;
      va_list args;
      va_start(args, format);
      len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
      va_end(args);
  
      if ( RTMP_debuglevel==RTMP_LOGCRIT )
          return;
  
      if ( !fmsg ) fmsg = stderr;
  
      if (neednl) {
          putc('\n', fmsg);
          neednl = 0;
      }
  
      if (len &gt; MAX_PRINT_LEN-1)
            len = MAX_PRINT_LEN-1;
      fprintf(fmsg, "%s", str);
      if (str[len-1] == '\n')
          fflush(fmsg);
  }
  </code></pre>