Python ctypes: envolviendo la clase c ++ con operadores

Quiero envolver una pequeña prueba de clase C ++ para usar en Python usando ctypes. La clase se llama Edge y tiene un operador de comparación de amigos (==). Estoy teniendo dificultades para implementar la función de comparación en el código de python envoltorio.

Un encabezado de Edge sucinto es:

 class Edge { private: int p1, p2; public: Edge(const int pp1, const int pp2); ~Edge(){}; friend bool operator==(const Edge &e1, const Edge &e2); }; 

El envoltorio de python que he escrito es:

 from ctypes import * lib = cdll.LoadLibrary('./libedge.so') lib.Edge_new.argtypes = [c_int, c_int] lib.Edge_new.restype = c_void_p lib.compare_edge.argtypes = [c_void_p, c_void_p] lib.compare_edge.restype = c_bool class Edge(object): def __init__(self, pp1, pp2): self.obj = lib.Edge_new(c_int(pp1), c_int(pp2)) def __eq__(self, other): return lib.compare_edge(self.obj, c_void_p(other)) 

Donde, Edge_new y compare_edge son rutinas de C ++ que se definen como:

 #include "Edge.hpp" extern "C" { Edge* Edge_new(const Int32 pp1, const Int32 pp2) { return new Edge(pp1, pp2); } bool compare_edge(Edge *e1, Edge *e2) { return *e1 == *e2; } } 

El constructor funciona bien. Cuando comparo dos objetos de borde e1 == e2 obtengo el siguiente error de tipo:

 Traceback (most recent call last): File "Edge.py", line 21, in  print e1 == e2 File "Edge.py", line 16, in __eq__ return lib.compare_edge(self.obj, c_void_p(other)) TypeError: cannot be converted to pointer 

Entiendo lo que significa el error, y muy probablemente por qué algo va mal, pero no sé cómo solucionarlo. Estoy comstackndo código C ++ con gcc 4.7 y el intérprete de python es de 64 bits.

El problema es que estás intentando convertir un objeto de Python en un void * , en lugar del void * que ya adjuntas al atributo obj ese objeto.

Debería ser tan simple como cambiar …

 def __eq__(self, other): return lib.compare_edge(self.obj, c_void_p(other)) 

…a…

 def __eq__(self, other): return lib.compare_edge(self.obj, other.obj) 

La llamada explícita a c_void_p debería ser innecesaria, ya que ya declaró los tipos en la línea …

 lib.compare_edge.argtypes = [c_void_p, c_void_p]