如何将 C 中的内存地址转换为 python ctypes 调用?
抱歉,如果标题不准确,我不能 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)
Sorry if the title isn't accurate, I am not 100% sure it describes the situation correctly:
I am attempting to interface with the FreeTDS C-library using Python's ctypes module. I have some code running surprisingly well, but have run into one snag. I am not sure how to to translate the last parameter of the dbbind() call below into ctypes.
The C example I am following is:
/* 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);
So, A) how do I define my variables in Python as variable types from the library and B) how do I translate "(BYTE *)&company_name" etc. into ctypes calls?
Thank you!
Solution: thanks to Zuljin, I was able to work out the following:
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为你应该检查这些 DBINT、DBCHAR、DBFLT8 类型背后的内容。可能是 int、char 和 double。对于这些基本类型,您可以找到 ctypes - 可能是 c_int、c_char、c_double。
因此,您现在可以创建将保存函数返回值的 python 实例。要将这些值作为指针参数传递,您需要使用
byref()
函数。像这样的东西:编辑:对于名称,您必须创建空字符缓冲区。为此,ctypes 提供了 2 个函数 create_string_buffer 和 create_unicode_buffer。这些函数的输出对象可以直接传递给您的函数。下面是 Windows 上正常和 unicode scanf 函数调用的示例(在 Python 3 中)。
I think you should just check what is behind these DBINT,DBCHAR,DBFLT8 types. Probably this is int, char and double. And for those basic types you can find ctypes - probably c_int, c_char, c_double.
So you can now create python instances that will hold values returned by function. To pass these values as a pointer parameter you need to use
byref()
function. Something like this:EDIT: For name you have to create empty character buffer. To do that ctypes provide 2 functions create_string_buffer and create_unicode_buffer. Output object from these functions can be directly passed to your function. Here is example (in Python 3) of normal and unicode scanf function call on Windows.