2010-06-18 74 views
2

我想調用一個外部庫函數,該函數返回a NULL-terminated array of NULL-terminated stringsPython ctypes - 如何處理字符串數組

kernel32 = ctypes.windll.kernel32 
buf = ctypes.create_unicode_buffer(1024) 
length = ctypes.c_int32() 
if kernel32.GetVolumePathNamesForVolumeNameW(ctypes.c_wchar_p(volume), 
    buf, ctypes.sizeof(buf), ctypes.pointer(length)): 
    ## ??? 

換句話說:

buf = ctypes.create_unicode_buffer(u'Hello\0StackOverflow\0World!\0') 

如何訪問buf所有內容作爲一個Python列表?buf.value只能達到第一個NULL。

在C這將是這樣的:

while (*sz) {; 
    doStuff(sz); 
    sz += lstrlen(sz) + 1; 
} 

回答

5

發現ctypes.wstring_at()ctypes.addressof()後,我得到這個:

def wszarray_to_list(array): 
    offset = 0 
    while offset < ctypes.sizeof(array): 
     sz = ctypes.wstring_at(ctypes.addressof(array) + offset*2) 
     if sz: 
      yield sz 
      offset += len(sz)+1 
     else: 
      break 
3

,如果你發佈運行的代碼會更容易些:這個呼叫要找一份合適的卷名是一個有點疼痛。 buf是包含length個字符的數組。最後兩個字符是空值,因此忽略它們,使用''.join()將數組轉換爲字符串,並將其分割爲空字符。

import ctypes 
kernel32 = ctypes.windll.kernel32 

def volumes(): 
    buf = ctypes.create_unicode_buffer(1024) 
    length = ctypes.c_int32() 
    handle = kernel32.FindFirstVolumeW(buf, ctypes.sizeof(buf)) 
    if handle: 
     yield buf.value 
     while kernel32.FindNextVolumeW(handle, buf, ctypes.sizeof(buf)): 
      yield buf.value 
     kernel32.FindVolumeClose(handle) 

def VolumePathNames(volume): 
    buf = ctypes.create_unicode_buffer(1024) 
    length = ctypes.c_int32() 
    kernel32.GetVolumePathNamesForVolumeNameW(ctypes.c_wchar_p(volume), 
     buf, ctypes.sizeof(buf), ctypes.pointer(length)) 
    return ''.join(buf[:length.value-2]).split('\0') 

for volume in volumes(): 
    print volume 
    print VolumePathNames(volume) 

當我運行這個所有的列表只包含一個名稱,但如果你仔細檢查長度,這是他們包含在返回的緩衝區。

+0

「這個呼叫要找一份合適的卷名是有點痛」 - 'mountvol'將列出所有卷的GUID。 – grawity 2010-06-19 18:49:26

+0

「當我運行這個時,所有的列表都只包含一個名字,但如果你仔細檢查長度,那麼它們就包含在返回的緩衝區中。」 - 幾乎總是這樣,是的,但是除了驅動器盤符之外,我的一些可移動驅動器可以通過Unix風格的安裝點到達。無論哪種方式,我只是尋找一個通用的解決方案,不一定''GetVolume ...()' - 具體。但是'split('\ 0')'現在已經夠好了。 – grawity 2010-06-19 18:50:19

相關問題