如何将C中内存地址的强制转换转换为python ctypes调用?
抱歉,如果标题不准确,我不能100%确定它是否正确描述了情况: 我试图使用Python的ctypes模块与FreeTDS C库进行接口。我有一些代码运行得出奇地好,但遇到了一个障碍。我不知道如何将下面dbbind()调用的最后一个参数转换为ctypes 下面的C示例是:如何将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];
/* 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?您的建议,再加上更改绑定常量,最终使我找到了正确的位置。谢谢