如何将C中内存地址的强制转换转换为python ctypes调用?

如何将C中内存地址的强制转换转换为python ctypes调用?,python,ctypes,freetds,Python,Ctypes,Freetds,抱歉,如果标题不准确,我不能100%确定它是否正确描述了情况: 我试图使用Python的ctypes模块与FreeTDS C库进行接口。我有一些代码运行得出奇地好,但遇到了一个障碍。我不知道如何将下面dbbind()调用的最后一个参数转换为ctypes 下面的C示例是: /* these variable types are defined in the FreeTDS library */ DBINT customer_id; DBCHAR company_name[255];

抱歉,如果标题不准确,我不能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);
/*这些变量类型在FreeTDS库中定义*/
DBINT客户识别码;
DBCHAR公司名称[255];
DBFLT8平均收入;
/*  */
/*现在将返回的列绑定到变量*/
/*字节在FreeTDS库中定义*/
dbbind(dbconn,1,INTBIND,0,(字节*)&客户id);
dbbind(dbconn,2,NTBSTRINGBIND,0,(字节*)&公司名称);
dbbind(dbconn,3,FLT8BIND,0,(字节*)&平均收入);
那么,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)
将ctypes导入为ct
#
cid=ct.c_int()
cname=ct.创建字符串缓冲区(256)
cavgincome=ct.c_float()
dbbind(cdbconn,1,INTBIND,0,ct.byref(cid))
dbbind(cdbconn,2,NTBSTRINGBIND,0,cname)
dbbind(cdbconn,3,REALBIND,0,ct.byref(cavgincome))
而dtlib.dbnextrow(cdbconn)!=没有更多行:
打印“%s |%s |%s%”(cid,cname.value,cavgincome)

我认为您应该检查这些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)

我认为您应该检查这些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)

谢谢你的建议。所以你认为我不需要对字节强制转换做任何事情吗?Char255=c_char*255 company_name=Char255()dbbind(dbconn,1,VARYCHARBIND,0,byref(company_name))上面给了我一个seg错误。为什么是255?您的数组长度为256?您的建议,再加上更改绑定常量,最终使我找到了正确的位置。谢谢谢谢你的建议。所以你认为我不需要对字节强制转换做任何事情吗?Char255=c_char*255 company_name=Char255()dbbind(dbconn,1,VARYCHARBIND,0,byref(company_name))上面给了我一个seg错误。为什么是255?您的数组长度为256?您的建议,再加上更改绑定常量,最终使我找到了正确的位置。谢谢