0

抱歉,如果标题不准确,我不能 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 *)&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)
4

1 回答 1

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)
于 2011-04-10T09:40:35.883 回答