用Python的ctypes库,通过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 -*-
在暑假,无所事事中,但没在内卷。