Python 3.x ctype c_wchar_p 和 c_char_p 返回状态不同于 ctypes doc

Posted

技术标签:

【中文标题】Python 3.x ctype c_wchar_p 和 c_char_p 返回状态不同于 ctypes doc【英文标题】:Python 3.x ctype c_wchar_p and c_char_p return status different from ctypes doc 【发布时间】:2016-11-13 18:48:05 【问题描述】:

Python 版本

Python 3.5.2

问题

当我尝试使用 ctypes 调用 C DLL 时,我注意到了这个问题,C 函数类似于:

MEASURE_API int InitTester(char *ipAddress)

所以我需要将 IP 地址字符串(例如,192.168.100.100)从 Python 传递给 ctypes,根据 Python 3.5 的 ctypes doc,我尝试了 c_wchar_p 和 c_char_p,但它们都不起作用,我从 c dll 端重新运行错误代码。我对这个 dll 进行了一些其他函数调用,传递了 c_int、c_void_p、c_bool 和其他数据类型,这些都可以。回溯,发现 c_wchar_p 和 c_char_p 返回结果的行为与基于 ctypes doc 的行为不同。来自 Python 3.5 的 ctypes 文档:

>>> c_wchar_p("Hello, World")
c_wchar_p('Hello, World')

它返回 ctypes 字符串。 但我在 Python 控制台中执行相同 cmd 的结果:

>>> from ctypes import *
>>> c_wchar_p("Hello, World")
c_wchar_p(1374004842736)
>>> c_wchar_p("Hello, World")
c_wchar_p(1374004841680)
>>> c_wchar_p("Hello, World")
c_wchar_p(1374004842736)

所以看起来原来的字符串部分可能变成了内存地址。深入挖掘,发现它是否是 Python 2.x(默认编码为 ASCII),然后返回显示字符串,如 Python 3.5 ctypes doc 所示。但在 Python 3.x(默认编码为 UTF-8)中,它总是返回数字,行为与文档不同。在多台电脑上检查。并理解了我们可以使用 .value 返回原始字符串的部分。但它不能传递给必须是 ctype 的 C 函数。

问题

谁能提供关于行为 ctypes 的解释? 以及如何解决这个问题,以便在 Python3.5 中获得与 ctype doc 相同的行为,然后使 call c dll 工作?

先谢谢了~

【问题讨论】:

错误是什么?您是否尝试过使用create_string_buffer?它不是const arg 的事实表明您需要传递一些允许变异的东西,这就是create_string_buffer 似乎所做的。 【参考方案1】:

我现在非常确定您应该使用create_string_buffer 而不是c_char_p 将字符串传递给您的C 函数;非const 签名表示突变,并且需要文档中所述的字符缓冲区:

然而,你应该小心,不要将它们传递给期望指向可变内存的函数。如果你需要可变内存块,ctypes 有一个create_string_buffer() 函数,它以各种方式创建这些。可以使用 raw 属性访问(或更改)当前内存块的内容;如果您想以 NUL 终止字符串的形式访问它,请使用 value 属性。

(强调我的)

所以本质上,create_string_buffer(b'192.168.100.100')

除此之外,似乎文档可能确实在这方面有所欠缺。 __repr__ for c_char_p and c_wchar_p 的实现返回它们的名称,并在创建指向它们的内存缓冲区的指针后,返回 .valuec_void_p 指针。

【讨论】:

感谢您的快速回复,吉姆。测试者在实验室,我明天上班后会试用并提供更新~ 嗨,Jim,我尝试了 create_string_buffer() 和 create_unicode_buffer(),但调用 c 函数时仍然返回错误消息。错误消息是_无法连接到服务器!错误状态 = -1 b'未知错误条件。' _。我想我会满足测试器供应商的详细信息,谢谢你的帮助~ @AlexWang,如果您包含来自库文档的相关信息(对于 DLL,而不是 Python / ctypes)而不是让其他人依赖于您的解释,它会有所帮助。也许图书馆不想要一个虚线四边形 IP 地址?我怀疑它是否真的关心它是一个可变缓冲区。 C 程序员经常懒得使用const,但在这方面小心一点也无妨。 @eryksun,C 函数本身只返回 无法连接到服务器! error status = -1, b'Unknown error condition.' 在控制台中,有关更多详细信息,我需要与供应商联系以获取有关此功能的更多信息。会回来更新。谢谢~

以上是关于Python 3.x ctype c_wchar_p 和 c_char_p 返回状态不同于 ctypes doc的主要内容,如果未能解决你的问题,请参考以下文章

『Python CoolBook』使用ctypes访问C代码_下

linux 安装python3.7 报错No module named '_ctypes'

从 python ctypes 调用 CPP 函数

使用 HRESULT(python) 的 ctypes

在 Python ctypes 中转换为数组

Python - 将字符串对象转换为 ctypes (unsigned char *)