Python-ctypes,每日实现一个C语言数据结构挑战!

  用Pythonctypes库,通过DLL调用C语言函数,每日实现一个C语言数据结构。

  今天是第一天

  今日的是 SqQueue循环列表

  C语言(DLL)部分:

#include "pch.h"
#define CFUNCTIONS extern "C"
#define cdef __declspec(dllexport)
#include <stdio.h>
#include <stdlib.h>
#define ElemType int
#define Status int
#define OVER -1
#define OK 0
#define ERROR 1

CFUNCTIONS{

typedef struct
{
	int MAXSIZE;
}Info;


/*第一天 循环队列SqQueue*/
typedef struct
{
	int front;
	int rear;
	ElemType* base;
	Info info;
	/*
	* Status (*InitSqQueue)(SqQueue* queue ,int MAXSIZE) 初始化
	* Status (*EnSqQueue)(SqQueue* queue, ElemType value) 添加
	* Status (*DeSqQueue)(SqQueue* queue) 删除
	* Status (*KillSqQueue)(SqQueue* queue) 摧毁
	* Status (*isEmptySqQueue)(SqQueue queue) 空
	* Status (*isFullSqQueue)(SqQueue queue) 满
	* Status (*ClearSqQueue)(SqQueue* queue) 清空
	* Status (*AtozSqQueue)(SqQueue queue) 遍历
	* int (*LenSqQueue)(SqQueue* queue) 长度
	*/
}SqQueue;

//长度
cdef int LenSqQueue(SqQueue* queue)
{
	return (queue->rear - queue->front + queue->info.MAXSIZE) % queue->info.MAXSIZE;
}

//初始化
cdef Status InitSqQueue(SqQueue* queue, int MAXSIZE)
{
	if (!(queue->base = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE)))
		return OVER;
	queue->front = queue->rear = 0;
	queue->info.MAXSIZE = MAXSIZE;
	return OK;
}

//入队
cdef Status EnSqQueue(SqQueue* queue, ElemType value)
{
	if (!queue->base) return ERROR;

	if (!((queue->rear + 1) % queue->info.MAXSIZE - queue->front)) return OVER;

	queue->base[queue->rear++] = value;
	queue->rear %= queue->info.MAXSIZE;
	return OK;
}

//出队
cdef ElemType DeSqQueue(SqQueue* queue)
{
	if (!queue->base) return ERROR;

	if (!LenSqQueue(queue)) return OVER;

	ElemType value = queue->base[queue->front++];
	queue->front %= queue->info.MAXSIZE;
	return value;
}

//删除
cdef Status KillSqQueue(SqQueue* queue)
{
	if (!queue->base) return ERROR;

	delete queue->base;

	return OK;
}

//是否空
cdef Status isEmptySqQueue(SqQueue queue)
{
	return (!(queue.rear - queue.front)) ? 1 : 0;
}

//是否满
cdef Status isFullSqQueue(SqQueue queue)
{
	return (((queue.rear + 1) % queue.info.MAXSIZE) == queue.front) ? 1 : 0;
}

//清空
cdef Status ClearSqQueue(SqQueue* queue)
{
	if (!queue->base) return ERROR;

	queue->front = queue->rear = 0;

	return OK;
}


}

Python部分:

# -*- coding: utf-8 -*-

from typing import Any, NoReturn ,NewType ,Callable, Type
from ctypes import *
from os import path
from sys import stderr

Array: NewType = NewType("Array" ,Any)
Ref: NewType = NewType("Ref" ,Any)
Status: c_int = c_int
ElemType: c_int = c_int


#对应Info结构体类型
class __Info__(Structure):
    _fields_: list[tuple] = [("MAXSIZE" ,c_int)]
    

#对应SqQueue结构体类型
class __SqQueue__(Structure):
    _fields_: list[tuple] = [
            ("front" ,c_int) ,
            ("rear" ,c_int) ,
            ("base" ,POINTER(c_int)) ,
            ("info" ,__Info__)
        ]
    

class SqQueue(object):
    
    #加载DLL
    def __LoadDLL(self ,name: str) -> int:
        if not path.exists(name):
            stderr.write("FileNotFoundError!\nNo {}!\n".format(name))
            return 0
        self.__dll: Any = cdll.LoadLibrary(name=name)
        return 1
        
    #设置C语言函数类型和其参数类型
    def __ConfigCFunctions(self) -> NoReturn:
        self.__InitSqQueue.argtypes: list[Type] = [POINTER(__SqQueue__) ,ElemType]
        self.__InitSqQueue.restype: Type = Status
        
        self.__EnSqQueue.argtypes: list[Type] = [POINTER(__SqQueue__) ,ElemType]
        self.__EnSqQueue.restype: Type = Status
        
        self.__DeSqQueue.argtypes: list[Type] = [POINTER(__SqQueue__)]
        self.__DeSqQueue.restypes: Type = c_int
        
        self.__ClearSqQueue.argtypes: list[Type] = [POINTER(__SqQueue__)]
        self.__ClearSqQueue.restype: Type = Status
        
        self.__KillSqQueue.argtypes: list[Type] = [POINTER(__SqQueue__)]
        self.__KillSqQueue.restype: Type = Status
        
        self.__isEmptySqQueue.argtypes: list[Type] = [__SqQueue__]
        self.__isEmptySqQueue.restype: Type = c_int
        
        self.__isFullSqQueue.argtypes: list[Type] = [__SqQueue__]
        self.__isFullSqQueue.restype: Type = c_int
        
        self.__LenSqQueue.argtypes: list[Type] = [POINTER(__SqQueue__)]
        self.__LenSqQueue.restype: Type = c_int
    
    #加载C语言函数
    def __LoadCFunctions(self) -> NoReturn:
        self.__InitSqQueue: Callable = self.__dll.InitSqQueue
        self.__EnSqQueue: Callable = self.__dll.EnSqQueue
        self.__DeSqQueue: Callable = self.__dll.DeSqQueue
        self.__KillSqQueue: Callable = self.__dll.KillSqQueue
        self.__isEmptySqQueue: Callable = self.__dll.isEmptySqQueue
        self.__isFullSqQueue: Callable = self.__dll.isFullSqQueue
        self.__ClearSqQueue: Callable = self.__dll.ClearSqQueue
        self.__LenSqQueue: Callable = self.__dll.LenSqQueue
    
    #初始化
    def __init__(self ,path: str ,MAXSIZE: int) -> NoReturn:

        if not self.__LoadDLL(name=path):
            return
        self.__LoadCFunctions()
        self.__ConfigCFunctions()
        
        array: Array = (c_int * MAXSIZE)()
        queue: Ref[Array] = POINTER(c_int).from_buffer(array)
        self.__info: __Info__ = __Info__(MAXSIZE)
        self.__queue: __SqQueue__ = __SqQueue__(0 ,0 ,queue ,self.__info)
        
        self.__InitSqQueue(byref(self.__queue) ,c_int(MAXSIZE))
        
    #对应LenSqQueue
    def __len__(self) -> int:
        return self.__LenSqQueue(byref(self.__queue))

    #对应EnSqQueue
    def push(self ,value: int) -> NoReturn:
        self.__EnSqQueue(byref(self.__queue) ,c_int(value))

    #对应DeSqQueue
    def pop(self) -> c_int:
        return self.__DeSqQueue(byref(self.__queue))

    #对应ClearSqQueue
    def clear(self) -> c_int:
        return self.__ClearSqQueue(byref(self.__queue))

    #对应KillSqQueue
    def destroy(self) -> c_int:
        return self.__KillSqQueue(byref(self.__queue))

    #对应isEmptySqQueue
    @property
    def is_empty(self) -> c_int:
        return self.__isEmptySqQueue(self.__queue)

    #对应isFullSqQueue
    @property
    def is_full(self) -> c_int:
        return self.__isFullSqQueue(self.__queue)

-*- 24/8/4 -*-

在暑假,无所事事中,但没在内卷。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值