CircuitPython is a weird Adafruit invention so I can't comment on their code, but if you want to include c code I suggest you explore Ctypes in normal python to learn the ropes.
There are a few different ways of calling c from python but I use Ctypes in my code (which is what Adafruit appear to use).
It took me a while to get my head around calling c from python and I have used other methods but found this the simplest (at least for simple code). I use this to call my shared GPIO library from python.
I have included a simple example I used to test lists.
The link in the c code has other examples.
#! /usr/bin/env python3
# import os
# import subprocess
# 2022-12-08
List test
import ctypes
clibrary = ctypes.CDLL('/home/ian/PyTest/ctype1/clibrary.so')
L = ['A', 'B', 'C']
lB = [97, 98, 99]
BA = bytes(lB)
print(BA)
B2 = bytes([97, 98, 0, 99])
pr_list = clibrary.pr_list
pr_list.argtypes = [ctypes.c_char_p, ctypes.c_int]
pr_list(BA, len(BA))
pr_list(B2, len(B2))
case_list = clibrary.case_list
case_list.argtypes = [ctypes.c_char_p, ctypes.c_int]
BC = bytes([0]*len(BA))
print("BA = ", BA)
print("B2 = ", B2)
print("BC = ", BC)
copy_list = clibrary.copy_list
copy_list.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int]
copy_list(BA, BC, len(BA))
print("BC = ", BC)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// https://coderslegacy.com/python/ctypes-tutorial/
// gcc -fPIC -shared -o clibrary.so clibrary.c
void prompt(int num) { printf("The number %d was entered", num); }
int add(int num1, int num2) { return num1 + num2; }
void display(char *str) { printf("%s", str); }
void increment(char *str) {
for (int i = 0; str[i] != 0; i++) {
str[i] = str[i] + 1;
}
}
char *alloc_memory(void) {
char *str = strdup("Hello World");
printf("Memory allocated...\n");
return str;
}
void free_memory(char *ptr) {
printf("Freeing memory...\n");
free(ptr);
}
// ______________
struct Point {
int x;
int y;
};
void printPoint(struct Point p) { printf("%d %d\n", p.x, p.y); }
struct Point getPoint() {
struct Point temp;
temp.x = 50;
temp.y = 100;
return temp;
}
// ______________
void floatest(float num) {
printf("The number %f was entered\n", num);
printf("The number %x was entered\n", num);
}
// ______________
char *GetStr(void)
// { return "TestString"; }
// { return "{'A':13, 'B':14, 'C':'pi'}"; }
{
return "{'p1_revision':3, 'type':'Pi 3 Model B+', 'ram':'1G', "
"'processor':'BCM2837', 'manufacturer':'Sony', 'revision':'a020d3'}";
}
// 2022-12-04
void pr_pointer(char *str) { printf("%s", str); }
// 2022-12-07
void pr_list(const unsigned char *lst, unsigned count) {
printf("%s %d\n", lst, count);
for (int i = 0; i < count; i++) {
printf("%d ", lst[i]);
}
printf("\n");
}
// 2022-12-07
void case_list(unsigned char *lst, unsigned count) {
printf("%s %d\n", lst, count);
for (int i = 0; i < count; i++) {
lst[i] = toupper(lst[i]);
printf("%d ", lst[i]);
}
printf("\n");
}
void copy_list(unsigned char *lst1, char *lst2, unsigned count) {
for (int i = 0; i < count; i++) {
lst2[i] = toupper(lst1[i]);
}
}