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

时间:2016-08-30 05:43:06

标签: python dll 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

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

有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

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

最好将C pathinfo函数更改为某些类似

的函数
size_t pathinfo(char* path, size_t bsize);

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

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*时的字符编码以及strbytes / ctypes的更改关于Python 2和Python 3。

答案 1 :(得分:0)

Haven没有做到,但做了以下事情:

例如,要传递ints数组,请使用:

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

Ints20 = c_int * 20

创建一个实例:

data = Ints20()

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

values = list(data)

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

Chars20 = c_char * 20
path = Chars20()

然后:

self.demoDLL.pathinfo(path)

对于c_char数组,不需要使用list函数,但这可行:

return path.value