Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ctypes和构建元类:TypeError:*类*实例而不是LP_*类*实例_Python_C_Ctypes_Typeerror_Metaclass - Fatal编程技术网

Python ctypes和构建元类:TypeError:*类*实例而不是LP_*类*实例

Python ctypes和构建元类:TypeError:*类*实例而不是LP_*类*实例,python,c,ctypes,typeerror,metaclass,Python,C,Ctypes,Typeerror,Metaclass,故事:我使用python与C进行通信,反之亦然。我还制作了C共享库,我也在尝试接口。在开发的这一步,它只是一个简单的库,在深入代码之前测试所有的概念。它是用C++编写的,用外部的“C”来显示函数,没有任何幻想。我已经用原始参数/返回类型、指针和函数回调测试了函数 现在我想通过structs。由于我是一个懒惰的程序员,我计划把C++结构传递给一个统一的C表示(即,简单字典和列表的组合),并将它处理到Python,它将把它转换成真正的Python对象(即,Python字典和列表的组合)。 问题:为

故事:我使用python与C进行通信,反之亦然。我还制作了C共享库,我也在尝试接口。在开发的这一步,它只是一个简单的库,在深入代码之前测试所有的概念。它是用C++编写的,用外部的“C”来显示函数,没有任何幻想。我已经用原始参数/返回类型、指针和函数回调测试了函数

现在我想通过structs。由于我是一个懒惰的程序员,我计划把C++结构传递给一个统一的C表示(即,简单字典和列表的组合),并将它处理到Python,它将把它转换成真正的Python对象(即,Python字典和列表的组合)。

<强>问题:为了实现这一点,我在C++中定义了一个模板字典,它的实现是,只为测试,一个键值对的链表,字典中有根。然后,对于每个需要专门化的函数,该专门化的typedef被用作C结构

代码如下所示(不是实际代码):

#包括
模板
结构节点
{
钥匙(t)钥匙;;
价值(t)价值;;
};
模板
结构指令
{
typedef DictNode节点;
节点根;
};
typedef Dict_int_char;
外部“C”Dict_int_char*示例_new()
{
Dict_int_char*结果;
结果=(Dict_int_char*)malloc(sizeof(Dict_int_char));
返回结果;
}
外部“C”无效示例\u删除(Dict\u int\u char*值)
{
自由(价值);
}
现在,在python中,为了避免为每个专门化创建一个类,我采用了相同的方法。一个方法将为我创建给定键值类型的专用类

代码如下所示(实际代码):

导入类型
导入ctypes
#这是为了提供模块内部的一些隐藏
#关于一种更具蟒蛇风格的方法的建议被欣然接受
类内件:
"""
创建类以与从
C++类模板特化。这个方法是
模板类的类型,创建要
与专用类(已被typedef'd)的接口
并返回它们以与ctypes一起使用。
"""
@静力学方法
定义类创建(键,值):
#向前声明类
类InterfaceListNode(ctypes.Structure):
通过;
类接口列表(ctypes.Structure):
通过;
####节点
#节点类
nodeType=接口列表节点;
#指向节点类的指针
nodeTypePointerType=ctypes.POINTER(nodeType);
#节点类的字段(下一个、键、值)
nodeType._字段\=[(“下一步”,nodeTypePointerType),
(key,key t),,
(“价值”,value_t)];
#函数创建节点指针
def nodeTypePointerCreate(cls,值=无):
如果(值为无):
返回nodeTypePointerType();
其他:
返回nodeTypePointerType(值);
#将函数绑定到节点类
nodeType.pointer=types.MethodType(nodeTypePointerCreate,nodeType);
####口述
#听写课
dictType=接口列表;
#指向dict类的指针
dictTypePointerType=ctypes.POINTER(dictType);
#dict了解其节点的类型非常有用
dictType.\u节点类型=节点类型;
#dict类的字段(根)
dictType._字段\=[(“根”,ctypes.POINTER(nodeType))];
#函数创建dict指针
def DICTYPEPOINTERCREATE(cls,值=无):
如果(值为无):
返回dictTypePointerType();
其他:
返回dictTypePointerType(值);
#将函数绑定到dict类
dictType.pointer=types.MethodType(dictTypePointerCreate,dictType);
#用于调试
打印“内部元类生成器”
打印十六进制(id(节点类型));
打印十六进制(id(dictType));
#只返回dict类,因为它知道它的节点类。
返回类型;
#创建一个新的专用dict
dictType_1=___内部.__DictClassCreate__(ctypes.c_uint,ctypes.c_char);
#获取此目录的节点类型
nodeType_1=dictType_1.\u nodeType;
#用于调试
打印“在脚本中”
打印十六进制(id(nodeType_1));
打印十六进制(id(dictType_1));
#尝试使用1个元素来实例此字典
#(非空根,空根,下一步)
dict_1=dictType_1(nodeType_1(nodeType_1.pointer(),0,'a'));
运行此代码时,将显示以下输出:

python SciCamAPI.py
Inside metaclass generator
0x249c1d8L
0x249c588L
In Script
0x249c1d8L
0x249c588L
Traceback (most recent call last):
  File "SciCamAPI.py", line 107, in <module>
    dict_1 = dictType_1(nodeType_1(nodeType_1.pointer(), 0, 'a'));
TypeError: incompatible types, InterfaceListNode instance instead of LP_InterfaceListNode instance
python SciCamAPI.py
内部元类生成器
0x249c1d8L
0x249c588L
手稿
0x249c1d8L
0x249c588L
回溯(最近一次呼叫最后一次):
文件“SciCamAPI.py”,第107行,在
dict_1=dictType_1(nodeType_1(nodeType_1.pointer(),0,'a'));
TypeError:类型不兼容,InterfaceListNode实例而不是LP_InterfaceListNode实例
从打印的输出中,我可以看到我使用了与方法中生成的相同的元类来实例化简单dict及其节点


我已经在谷歌上搜索了错误中可以添加的LP_uu,但是搜索LP_uuPython只会返回线性问题求解器和。根据对答案的理解,ctypes正在从nodeType_1.pointer()(最后一行)创建一个C样式的指针,但当node.next被声明为[(“next”,nodeTypePointerType),…](在nodeType.fields=…)时,这就是应该接收的指针。所以我很迷茫。

引用埃里克森的评论:


dictType\u 1.root
是一个
LP\u InterfaceListNode
字段,即
指针(InterfaceListNode)
,但您正在用
InterfaceListNode
初始化它,而不是指向它的指针。“LP”是指分段体系结构中的“长指针”,该体系结构具有近(段内)和远/长指针。Windows类型保留此前缀,即使它不再有意义,例如
LPVOID
LPWSTR
。cty
import types
import ctypes

# This is to provide some hiding of the module internals
# Suggestions on a more pythonic way are gladly accepted
class __Internals:
  """
  Creates class to interface with a C structure comming from a
  typedef'd C++ class template specialization. This method recieves
  the types of the template class, creates the ctypes classes to
  interface with the specialized class (which has been typedef'd)
  and returns them for usage with ctypes.
  """
  @staticmethod
  def __DictClassCreate__(key_t, value_t):
    # Foward declare the classes
    class InterfaceListNode(ctypes.Structure):
      pass;
    class InterfaceList(ctypes.Structure):
      pass;

    #### NODE
    # Node class
    nodeType = InterfaceListNode;
    # The pointer-to-node class 
    nodeTypePointerType = ctypes.POINTER(nodeType);
    # Fields of the node class (next, key, value)
    nodeType._fields_ = [("next", nodeTypePointerType),
                         ("key", key_t),
                         ("value", value_t) ];

    # Function to create a node pointer
    def nodeTypePointerCreate(cls, value=None):
      if(value is None):
        return nodeTypePointerType();
      else:
        return nodeTypePointerType(value);

    # Bind the function to the node class
    nodeType.pointer = types.MethodType(nodeTypePointerCreate, nodeType);

    #### DICT
    # Dict class
    dictType = InterfaceList;
    # The pointer-to-dict class 
    dictTypePointerType = ctypes.POINTER(dictType);
    # Useful for dict to know the types of it's nodes
    dictType._nodeType = nodeType;
    # Fields of the dict class (root)
    dictType._fields_ = [("root", ctypes.POINTER(nodeType))];

    # Function to create a dict pointer
    def dictTypePointerCreate(cls, value=None):
      if(value is None):
        return dictTypePointerType();
      else:
        return dictTypePointerType(value);

    # Bind the function to the dict class
    dictType.pointer = types.MethodType(dictTypePointerCreate, dictType);    

    # For debugging
    print 'Inside metaclass generator'
    print hex(id(nodeType));
    print hex(id(dictType));

    # Return just the dict class since it knows about it's node class.
    return dictType;

# Create a new specialized dict<c_uint, c_char>
dictType_1 = __Internals.__DictClassCreate__(ctypes.c_uint, ctypes.c_char);
# Obtain the node type of this dict
nodeType_1 = dictType_1._nodeType;

# For debugging
print 'In Script'
print hex(id(nodeType_1));
print hex(id(dictType_1));

# Try to instance this dictionary with 1 element
#(not NULL root, NULL root.next)
dict_1 = dictType_1(nodeType_1(nodeType_1.pointer(), 0, 'a'));
python SciCamAPI.py
Inside metaclass generator
0x249c1d8L
0x249c588L
In Script
0x249c1d8L
0x249c588L
Traceback (most recent call last):
  File "SciCamAPI.py", line 107, in <module>
    dict_1 = dictType_1(nodeType_1(nodeType_1.pointer(), 0, 'a'));
TypeError: incompatible types, InterfaceListNode instance instead of LP_InterfaceListNode instance
rootNode = nodeType_1(nodeType_1.pointer(), 0, 'a');
dict_1 = dictType_1(nodeType_1.pointer(rootNode));