2012-03-20 20 views
1

dllの他の関数のログを取得するためにdllによって使用されるコールバック関数を定義する際に問題があります。ここ は、cの関数である:ここでPythonコールバックctypes関数va_list

typedef void (RTMP_LogCallback)(int level, const char *fmt, va_list); 
void RTMP_LogPrintf(const char *format, ...); 

は私のpythonのコードです:

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 

問題は、ログが汚れて読めないということである。

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á%&: server BW = 2618572ä°Gj♀ 
☻: fd=2618556o÷Gjá%&: 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: <|±'☺>Property: < 
|±'☺>Property: <|±'OBJECT>(object begin)Property: <,´'☺>Property: <,´'☺>Property: <,´'☺>(object end)Property: <|±'OBJECT>(object begin)Property: <,´'☺ 
>Property: <,´'☺>Property: <,´'☺>Property: <,´'OBJECT>(object begin)Property: <▄ý'☺>(object end)Property: <,´'☺>Property: <,´'☺>(object end)(object en 
d)~÷Gjmt;, server invoking <☺>~÷Gj, received result for method call <☺>│°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: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'☺>(object end)~÷Gj?⌂;, server invoking <☺>~÷Gj8¶;, r 
eceived result for method call <☺>¶÷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: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'☺>(object end)~÷Gj?⌂;, server invoking <☺>~÷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: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'OBJECT>(object begin)Property: <,´'☺>Property: <,´'☺>Property: 
<,´'☺>Property: <,´'☺>(object end)(object end)~÷Gj?t;, server invoking <☺>~÷Gj┴t;, onStatus: ☺ä°Gj♀☻: fd=2618556N÷Gj?, received: invoke 2618572 bytes 
(object begin)Property: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'OBJECT>(object begin)Property: <,´'☺>Property: <,´'☺>Property: <,´'☺>Propert, ...etc 

私も印刷しようとしました

def logCallBack(level, message, va_list): 
    print message 
    return 0 

今回、ログは不完全です:

%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 

は、誰もがこの問題を解決するためにホ知っていますか?

ありがとうございます。

よろしく、Gontran

EDIT:

このスレッド(http://www.digipedia.pl/usenet/thread/15901/197/)によれば、ctypesのは、可変引数関数を扱う方法を提供しません。私はこの点を得る。しかし、なぜRTMP_LogPrintf()関数を使うのが正しく動作しないのですか?私は正しい議論に移っているという印象を持っています。詳細について

、RTMP_LogPrintf()はこのように定義されています

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 > MAX_PRINT_LEN-1) 
      len = MAX_PRINT_LEN-1; 
    fprintf(fmsg, "%s", str); 
    if (str[len-1] == '\n') 
     fflush(fmsg); 
} 
+0

を試してみてください☺' – Doboy

答えて

0

はのは、タイプva_listが本当に(間違っている可能性が前提です)c_void_pで表すことができると仮定しよう。そうであっても、次の呼び出しは間違っている:

dll.RTMP_LogPrintf(message, va_list) 

あなたがここに正確に二つの引数を渡して、2つ目はvoid *です。これは、あなたが書いたCの場合と同じミスです。

RTMP_LogPrintf(message, va_list); 

期待どおりに動作しません。そのため、2つの異なる機能printf()と​​があります。 Cでは、の引数を可変数で呼び出す移植可能な方法はありません(受信者には可変数の引数を指定できます)。 Python +のctypesではもちろんそうすることができますが、引数は単にva_listというオブジェクトではなく、Pythonオブジェクトのリストとして利用できる必要があります。

-1

は..私は `それが何を意味するか知っている私は悲しい顔を見て、この

CMPFUNC = CFUNCTYPE(c_int, c_int, POINTER(c_char), c_void_p)