2011-07-23 27 views
1

這是不一致:如何訪問ctypes結構的屬性,就好像它們是ctypes,而不是通過給定的包裝?

from ctypes import * 

class S(Structure): 
    _fields_ = [("x", POINTER(c_int)), ("y", c_int)] 

o = S() 
print o.x 
print o.y 

返回

<__main__.LP_c_int object at 0x10d3d08c0> 
0 

因此,在一種情況下,它返回一個​​類型,在另一種情況下,它直接返回該值。

我有一些更通用的代碼,我總是需要通過一個​​類型的實例(這也是可寫的,即寫入它將意味着在上面的示例中修改o)。對於o.x,這沒關係。但不適用於o.y

我怎樣才能得到o.yc_int實例?

+4

請停止標記您的標題。 –

+0

@Tomalak Geret'kal:我認爲他們更有用/可以這樣理解。另外,標籤稍有不同。標記定義了這個問題與什麼有關(僅此而已)。通過在標題中加入它,我也定義了這個問題的主題。說什麼是話題是更多的信息,而不僅僅是說它與什麼有關。 – Albert

+1

在標題中書寫標籤是多餘的。我們已經有一個清晰,簡潔,一致和可轉位的標籤系統。你在標題開頭寫了一個毫無意義的「Python:」就是打破了SO的期望(看看你的標題欄),給你的標題增加了雜亂的噪音,並纏繞着我。 「標題」字段的名稱是有原因的!寫出標題,而不是一些「主題」。沒有更多,沒有更多。 SO不是留言板或聊天論壇。 (而且我看不出寫「Python」是寫「Python」的「更多信息」。) –

回答

1

_ctypes來源看來,它們不會對簡單ctypes實例進行巧妙的自動轉換。

所以一個(醜陋的)解決方案是這樣的:

from ctypes import * 

def WrapClass(c): 
    class C(c): pass 
    C.__name__ = "wrapped_" + c.__name__ 
    return C 

class S(Structure): 
    _fields_ = [("x", POINTER(c_int)), ("y", WrapClass(c_int))] 

o = S() 
print o.x 
print o.y 
print o.y.value 
0

起初我以爲這將是不同的只是再版爲「正常」類型的方法,但一些測試後,我覺得有一些東西絕對有趣的去那裏。如果某物存在或不存在結構,它確實會有所作爲。

from ctypes import * 

class S(Structure): 
    _fields_ = [("x", POINTER(c_int)), ("y", c_int), ("z", c_float)] 

o = S() 

x = POINTER(c_int) 
y = c_int(1) 
z = c_float(2.2) 

print("In structure: x:{}, y:{}, z:{}".format(o.x, o.y, o.z)) 
print("Out of structure: x:{}, y:{}, z:{}".format(x, y, z)) 

In structure: x:<main.LP_c_long object at 0x000000000A090EC8>, y:0, z:0.0

Out of structure: x:, y:c_long(1), z:c_float(2.200000047683716)

特別,我想這應該被視爲錯誤行爲:

o.x.contents = y #OK 
o.x.contents = o.y #not OK!! 

Traceback (most recent call last): File "", line 1, in TypeError: expected c_long instead of int

相關問題