Python Forum
Python Extensions with C Custom PyObject?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python Extensions with C Custom PyObject?
#1
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:

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_H
So 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.
Reply


Messages In This Thread
Python Extensions with C Custom PyObject? - by babaliaris - Feb-13-2018, 10:08 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  I want to create custom charts in Python. js1152410 1 557 Nov-13-2023, 05:45 PM
Last Post: gulshan212
  importing same python library in multiple custom module escape_freedom13 6 3,876 May-10-2020, 07:01 PM
Last Post: escape_freedom13
  Importing Custom Modules in Python 3 Flexico 1 2,611 Aug-24-2019, 08:11 PM
Last Post: snippsat
  problem using custom exception handling in python srm 3 3,091 Jul-03-2019, 09:10 PM
Last Post: ichabod801
  Detecting file extensions ellipsis 1 2,317 Nov-15-2018, 07:44 AM
Last Post: buran
  Chrome Extensions austinr 0 2,227 Sep-21-2018, 05:22 AM
Last Post: austinr
  How to convert c_void_p PyObject back to void* lfdm 0 3,927 Feb-02-2017, 09:13 AM
Last Post: lfdm
  Custom widget in Python-Qt, 'live' at Qt Designer panoss 3 5,707 Jan-05-2017, 11:47 AM
Last Post: panoss

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020