如果标题不准确,我很抱歉,我不是100%确定它正确描述了这种情况:
我正在尝试使用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 *)&amp; 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)
答案 0 :(得分: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提供了2个函数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)