Feb-13-2018, 10:08 AM
Hello!
I'm trying to learn how to create python extensions with c. I read the documentation and i tried to make an example but a problem occurred which i don't know how to solve.
The extension is a Linked list which stores PyObjects. I want the end user to use my extension like this:
The list interface is this:
Thank you.
I'm trying to learn how to create python extensions with c. I read the documentation and i tried to make an example but a problem occurred which i don't know how to solve.
The extension is a Linked list which stores PyObjects. I want the end user to use my extension like this:
import List l = List.create() l.append(PyObject) l.remove(PyObject)The Problem is this:
PyObject *list_create(PyObject *self, PyObject *args) { //Create The List. List* new_list = List_Create(); //Raise Memory Exception. if (new_list == NULL) { PyErr_SetString(PyExc_MemoryError, "Memory is Full."); return NULL; } //PyObject Var. PyObject *obj = Py_BuildValue("&O", new_list); //Return it. return obj; }Obviously the line:
//PyObject Var. PyObject *obj = Py_BuildValue("&O", new_list);Is not working as i expected. I want somehow to create a PyObject that is pointing to a List * pointer and return it to the user.
The list interface is this:
#ifndef List_H #define List_H #include <Python.h> typedef struct Node { PyObject *value; struct Node *next; struct Node *prev; }Node; //List Structure. typedef struct List { Node *head; Node *tail; unsigned int count; }List; //Create a new List. List *List_Create(); //Append A New PyObject to the list. int List_Append(List * list_obj, PyObject *obj); //Remove a PyObject from the list. int List_Remove(List * list_obj, PyObject *obj); //Destroy the list. void List_Destroy(List * list_obj); #endif // !List_HSo basically i want somehow to wrap this functionality to a PyObject. Also i want somehow when the PyObject's reference count reaches zero, List_Destroy(List * list_obj) be called automaticly so the end user won't have to do something like that:
l.Destroy()If You Want to see the List implementation:
#include "List.h" List *List_Create() { //Create a new list object. List *new_list = (List *)PyMem_Malloc(sizeof(List)); //Initialize the list object. if (new_list != NULL) { new_list->count = 0; new_list->head = NULL; new_list->tail = NULL; } //Return it. return new_list; } int List_Append(List * list_obj, PyObject *obj) { /*Returns, -1 if memory is full, -2 if the list_obj is null, 0 on success. */ //Check if the list_obj is valid. if (list_obj != NULL) { //Create A new node. Node *new_node = (Node *)PyMem_Malloc(sizeof(Node)); //Memory is Full. if (new_node == NULL) return -1; //Initialize The Node// new_node->next = NULL; new_node->prev = NULL; new_node->value = obj; //Initialize The Node// //First Node to be added in the list. if (list_obj->head == NULL) { list_obj->head = new_node; list_obj->tail = new_node; list_obj->count++; } //Append a new node to the list. else { list_obj->tail->next = new_node; new_node->prev = list_obj->tail; list_obj->tail = new_node; list_obj->count++; } //Return successfully. return 0; } //list_object was not initialized. return -2; } int List_Remove(List * list_obj, PyObject *obj) { /*Returns, -1 if object to be deleted was not found in the list, -2 if the list_obj is null or the list is empty, 0 on success. */ //Check if the list_obj is valid. if (list_obj != NULL && list_obj->head != NULL) { //Start from the head of the list. Node *current = list_obj->head; //Find the node to be deleted. while (current != NULL) { //Check if you found the object to be deleted. if (current->value == obj) break; //Move to the next node. current = current->next; } //Node to be deleted was not found. if (current == NULL) return -1; //This is the last node inside the list. if (current->prev == NULL && current->next == NULL) list_obj->head = NULL; //Deleting the head of the list. else if (current->prev == NULL && current->next != NULL) list_obj->head = current->next; //Deleting the tail of the list. else if (current->next == NULL) list_obj->tail = current->prev; //Deleting an inner node. else current->prev = current->next; //Free the memory of the current node. PyMem_Free(current); //Return successfully. return 0; } return -2; } void List_Destroy(List * list_obj) { //Check if the list_obj is valid. if (list_obj != NULL && list_obj->head != NULL) { //Start from the head of the list. Node *current = list_obj->head; Node *temp; //Free All The Nodes. while (current != NULL) { temp = current; current = current->next; PyMem_Free(temp); } //Set the head to NULL. list_obj->head = NULL; } }Does anyone know how to do that?
Thank you.