如何使用ctypes访问字符指针值?

how to access character pointer value using ctypes?

我编写了一个 DLL,其中我获得了其中一个路径:

//demo.h
__declspec(dllexport) void pathinfo(char * path);

正在代码中执行某些操作以获取此路径。 现在,我编写的用于从 DLL 检索此路径的 python 脚本如下所示:

//demo.py
import sys 
import ctypes
from ctypes import *
class demo(object):
  def __init__(self):
     self.demoDLL=CDLL("demo.dll")

  def pathinfo(self):
     path=c_char()
     self.demoDLL.pathinfo.argtypes(POINTER(c_char))
     self.demoDLL.pathinfo.result=None
     self.demoDLL.pathinfo(byref(path))
     return path.value

if __name__=='__main__':
    abc=demo()
    path_info=abc.pathinfo()
    print "information of the path:",path_info

但我能看到的值只是路径的第一个字符,而不是整个字符串。

谁能帮我解决这个问题?

还没有做过,但是做了以下:

要传递 ints 的数组,例如,使用这个:

创建一个类型,比如 20 个整数:

Ints20 = c_int * 20

创建实例:

data = Ints20()

然后就可以通过data了。 使用 list 函数从 data 中提取数字:

values = list(data)

所以也许你可以对字符做同样的事情:

Chars20 = c_char * 20
path = Chars20()

然后:

self.demoDLL.pathinfo(path)

在 c_char 数组的情况下,不需要使用 list 函数,但是这个有效:

return path.value

您只看到第一个字符的原因是,通过调用 c_char(),您创建了一个 char 值,Python 将其视为 str(Python 2) 对象或 bytes (Python 3) 长度为 1 的对象。您可能很幸运没有遇到分段错误。通过在 C 代码中写入超过 1 个字节或长度 > 0 的以 NULL 结尾的字符串(例如使用 strcpy),您实际上会产生未检测到的缓冲区溢出。 ctypes不知道你在指针的内存位置写入了多少字节。 path.value 仍然是长度为 1 的 str / bytes

最好将 C pathinfo 函数改成类似

的东西
size_t pathinfo(char* path, size_t bsize);

使用 ctypes.create_string_buffer() 在您的 Python 代码中分配内存,并让 pathinfo return 成为结果的长度。当然,您必须在 C 代码中使用 bsize 检查 char* path 是否足够大。

Python-代码如下所示:

buf = ctypes.create_string_buffer(256)
result_len = pathinfo(buf, len(buf))
if result_len == len(buf):
    # buffer may have been too short,
    # try again with larger buffer
    ...
restlt_str = buf[0:result_len].decode('utf-8') # or another encoding

还要注意 C 域中的 NULL 终止符、将 python 字符串转换为 char* 和返回时的字符编码、关于 str / bytes 的更改在 ctypes 关于 Python 2 和 Python 3.