Feb-13-2018, 10:08 AM
(This post was last modified: Feb-13-2018, 10:11 AM by babaliaris.)
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.
