简体   繁体   English

ctypes:c_ulong类型神奇地更改为long

[英]ctypes: c_ulong type magically changed to long

I am writing the deepcopy function using python2.7 for my class. 我正在为我的班级使用python2.7编写deepcopy函数。 I encountered a weird problem My code is the following 我遇到了一个奇怪的问题,我的代码如下

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)

I get the following error: 我收到以下错误:

<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'

If you try: 如果你试试:

type(graph.numVertices)

The result is long 结果很长

I declared the numVertices as c_ulong(). 我将numVertices声明为c_ulong()。 Why does it become long? 为什么会变长?

The type of the fields in the structure is still maintained, but ctypes has some "helpful" conversions when reading the values: 结构中字段的类型仍保持不变,但是ctypes在读取值时具有一些“有用的”转换:

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_)

Output: 输出:

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

So you can write your code as the following and it will work correctly: 因此,您可以按照以下方式编写代码,它将正常运行:

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)

You can suppress the conversions by deriving from the classes, but it is usually unnecessary. 您可以通过派生这些类来抑制转换,但这通常是不必要的。 One use case is when using ctypes to call a function that returns an allocated string. 一种用例是使用ctypes调用返回分配的字符串的函数。 You need to suppress the c_char_p to Python byte string conversion so you can later free the c_char_p. 您需要禁止将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)

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM