2016-07-24 2 views
1

私はctypesモジュールを使用してGetTcpTable2を呼び出しています。 C++の例hereをPythonにゆっくりと変換しています。フィールドアクセス中にクラッシュしています。フィールドアクセスのctypesでPythonがクラッシュする

if __name__ == "__main__": 
    ptcp_table = POINTER(MIB_TCPTABLE2)() 
    ptcp_table = cast(create_string_buffer(sizeof(MIB_TCPTABLE2)), 
         POINTER(MIB_TCPTABLE2)) 
    ip_addr = in_addr() 
    size = c_ulong(sizeof(MIB_TCPTABLE2)) 
    retval = GetTcpTable2(ptcp_table, byref(size), TRUE) 
    if retval == ERROR_INSUFFICIENT_BUFFER: 
     ptcp_table = cast(create_string_buffer(size.value), 
          POINTER(MIB_TCPTABLE2)) 
     if not ptcp_table: 
      #throw error 
      pass 

    retval = GetTcpTable2(ptcp_table, byref(size), TRUE) 
    if retval == NO_ERROR: 
     print("Entries %d" % ptcp_table[0].dwNumEntries) 
     for i in range(0, ptcp_table[0].dwNumEntries): 
      print(ptcp_table[0].table[i]) 
      #ip_addr.S_un.S_addr = ptcp_table[0].table[i].dwLocalAddr 
      #ip_addr_string = inet_nota(ip_addr) 
      #print(ip_addr_string) 
      #print(string_at(ip_addr_string)) 

table[i]の離れdwLocalAddrにアクセスしようとすると、それがクラッシュ。

ptcp_table[0].table[i].dwLocalAddr 

ただ印刷するとクラッシュすることはありませんptcp_table[0].table[i]。 印刷して他のフィールドにアクセスしようとしました。 Pythonはちょうどクラッシュします。ここで

は私の構造体の定義です:GetTcpTable2

class MIB_TCPROW2(Structure): 
    _fields_ = [ 
     ("dwState", c_ulong), 
     ("dwLocalAddr", c_ulong), 
     ("dwLocalPort", c_ulong), 
     ("dwRemoteAddr", c_ulong), 
     ("dwRemotePort", c_ulong), 
     ("dwOwningPid", c_ulong), 
     ("dwOffloadState", c_int) 
    ] 


class MIB_TCPTABLE2(Structure): 
    _fields_ = [ 
     ("dwNumEntries", c_ulong), 
     ("table", POINTER(MIB_TCPROW2)) 
    ] 

定義:

GetTcpTable2 = windll.iphlpapi.GetTcpTable2 
GetTcpTable2.argtypes = [POINTER(MIB_TCPTABLE2), POINTER(c_ulong), c_char] 
GetTcpTable2.restype = c_ulong 

私はMIB_TCPTABLE2構造体の定義でその小さな勘を持っています。ドキュメントは、tableMIB_TCPROW2のサイズの配列であり、サイズがANY_SIZEであると言います。 iphlpapi.hファイルをチェックした結果、ANY_SIZEが1であることがさらに検査されます。そして、私はPOINTER(MIB_TCPROW2)のサイズがMIB_TCPROW2のサイズと等しくないことを知っています。

+1

'MIB_TCPTABLE2'は可変サイズの構造体です。 'dwNumEntries'は' table'配列の実際の大きさを示します。それをPythonにどのように表現するか私は考えていません。 –

+0

@JonathanPotterこれを指摘していただきありがとうございます。もう少し調べてみましたが、MIB_TCPTABLE2のクラスファクトリメソッドを作成して、可変長のバージョンを生成しました。 – jacob

+0

@ J.J.Hakala私はそれをすることができる2日前に待たなければならない。 (3時間後から) – jacob

答えて

1

構造体内の可変長フィールドの周りを回転する他のctypesの質問を調べ、answerに来て、ファクトリメソッドを使用してクラス定義を生成することを提案しました。

def MIB_TCPTABLE2_FACTORY(size): 
    class MIB_TCPTABLE2(Structure): 
     _fields_ = [ 
      ("dwNumEntries", c_ulong), 
      ("table", MIB_TCPROW2 * size) 
     ] 
    return MIB_TCPTABLE2 

私はsizeは、新しいタイプを作成するためにGetTcpTable2から返さ知ってこれを使用することができます。そして、私がしなければならないのはargtypesGetTcpTable2void *を受け入れるように変更することだけです。

GetTcpTable2.argtypes = [c_void_p, POINTER(c_ulong), c_char] 
関連する問題