2011-04-10 50 views
0

對不起,如果標題不準確,我不是100%確定它描述的情況正確:如何將C中的內存地址轉換爲python ctypes調用?

我試圖使用Python的ctypes模塊與FreeTDS C庫接口。我有一些代碼運行得非常好,但遇到了一個問題。我不知道如何將下面的dbbind()調用的最後一個參數轉換成ctypes。

我下面的C例子是:

/* these variable types are defined in the FreeTDS library */ 
    DBINT customer_id; 
    DBCHAR company_name[255]; 
    DBFLT8 avg_income; 

    /* <snip> */ 


    /* Now bind the returned columns to the variables */ 
    /* BYTE is defined in the FreeTDS library */ 
    dbbind(dbconn, 1, INTBIND, 0, (BYTE *)&customer_id); 
    dbbind(dbconn, 2, NTBSTRINGBIND, 0, (BYTE *)&company_name); 
    dbbind(dbconn, 3, FLT8BIND, 0, (BYTE*)&avg_income); 

所以,A)如何定義在Python我的變量,變量類型從庫和B)我怎麼翻譯「(BYTE *)& company_name「等轉換成ctypes調用?

謝謝!

解決方案:感謝Zuljin,我能夠制定出以下幾點:

import ctypes as ct 

#<snip> 

cid = ct.c_int() 
cname = ct.create_string_buffer(256) 
cavgincome = ct.c_float() 
dtlib.dbbind(cdbconn, 1, INTBIND, 0, ct.byref(cid)) 
dtlib.dbbind(cdbconn, 2, NTBSTRINGBIND, 0, cname) 
dtlib.dbbind(cdbconn, 3, REALBIND, 0, ct.byref(cavgincome)) 

while dtlib.dbnextrow(cdbconn) != NO_MORE_ROWS: 
    print '%s | %s | %s' % (cid, cname.value, cavgincome) 

回答

3

,我認爲你應該檢查什麼是這些DBINT,DBCHAR,DBFLT8類型後面。可能這是int,char和double。而對於那些基本的類型,你可以找到ctypes - 可能是c_int,c_char,c_double。 因此,您現在可以創建將保存由函數返回的值的python實例。要將這些值作爲指針參數傳遞,您需要使用byref()函數。事情是這樣的:

customer_id = c_int() 
dbbind(dbconn, 1, INTBIND, 0, byref(customer_id)) 

編輯:對於名稱,你必須創建空字符緩衝區。爲了做到這一點,ctypes提供了兩個函數create_string_buffer和create_unicode_buffer。這些函數的輸出對象可以直接傳遞給你的函數。這裏是Windows上正常和unicode scanf函數調用的例子(在Python 3中)。

from ctypes import * 
libc = cdll.msvcrt 

buf = create_string_buffer(256) 
buf_u = create_unicode_buffer(256) 

libc.scanf(b"%s", buf) 
libc.wscanf("%s", buf_u) 

print(buf.value) 
print(buf_u.value) 
+0

感謝您的建議。所以你不認爲我需要對BYTE演員做任何事情? – 2011-04-10 12:51:21

+0

Char255 = c_char * 255 company_name = Char255() dbbind(dbconn,1,VARYCHARBIND,0,byref(company_name)) 上面的代碼給了我一個seg錯誤。 – 2011-04-10 13:02:32

+0

爲什麼255?你的數組長256? – 2011-04-10 17:16:13

相關問題