ctypes:c_ulong类型神奇地改为long

时间:2018-02-11 23:40:00

标签: python ctypes

我正在使用python2.7为我的类编写 deepcopy 函数。我遇到了一个奇怪的问题 我的代码如下

import copy
from ctypes import *
class Graph (Structure):
    _fields_ = [("numVertices", c_ulong),
                    ("numEdges", c_ulong)]
    def __init__(self):
        self.numVertices = c_ulong(0)
        self.numEdges = c_ulong(0)

    def __deepcopy__(self,memo={}):
        newInstance = Graph()
        newInstance.numVertices = c_ulong(self.numVertices.value)
        newInstance.numEdges = c_ulong(self.numEdges.value)
        return newInstance

graph = Graph()
anotherGraph = copy.deepcopy(graph)

我收到以下错误:

<ipython-input-46-a0cdaa4ef3f7> in __deepcopy__(self, memo)
      9     def __deepcopy__(self,memo={}):
     10         newInstance = Graph()
---> 11         newInstance.numVertices = c_ulong(self.numVertices.value)
     12         newInstance.numEdges = c_ulong(self.numEdges.value)
     13         return newInstance

AttributeError: 'long' object has no attribute 'value'

如果您尝试:

type(graph.numVertices)

结果很长

我将numVertices声明为c_ulong()。它为什么变长?

1 个答案:

答案 0 :(得分:0)

结构中的字段类型仍然保留,但是ctypes有一些&#34;有用的&#34;读取值时的转换:

from ctypes import *

class Test(Structure):
    _fields_ = [('a',c_ulong),
                ('b',c_char_p)]

t = Test(1,b'hello')
print(type(t.a),type(t.b))
print(t._fields_)

输出:

<class 'int'> <class 'bytes'>
[('a', <class 'ctypes.c_ulong'>), ('b', <class 'ctypes.c_char_p'>)]

因此,您可以按照以下方式编写代码,它将正常工作:

import copy
from ctypes import *
class Graph (Structure):
    _fields_ = [("numVertices", c_ulong),
                    ("numEdges", c_ulong)]
    def __init__(self):
        self.numVertices = 0
        self.numEdges = 0

    def __deepcopy__(self,memo={}):
        newInstance = Graph()
        newInstance.numVertices = self.numVertices
        newInstance.numEdges = self.numEdges
        return newInstance

graph = Graph()
anotherGraph = copy.deepcopy(graph)

您可以通过派生类来抑制转换,但通常不需要。一个用例是使用ctypes调用返回已分配字符串的函数。您需要将c_char_p抑制为Python字节字符串转换,以便稍后释放c_char_p。

from ctypes import *

class ulong(c_ulong): pass
class char_p(c_char_p): pass

class Test(Structure):
    _fields_ = [('a',ulong),
                ('b',char_p)]

t = Test(1,b'hello')
print(type(t.a),type(t.b))
print(t.a,t.b)

输出:

<class '__main__.ulong'> <class '__main__.char_p'>
<ulong object at 0x0000000006263748> char_p(b'hello')