Python, C и Ctypes - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Имеется код на Python
def nearest(color):
    near = 1000000
    filename = ''
    for doc in DOCS:
        f = doc['path']
        dist = distance(color[0], doc['r'], color[1], doc['g'], color[2], doc['b'])
        if dist < near:
            near = dist
            f_d = doc
            filename = f
    DOCS.remove(f_d)
    return filename
Color - tuple из 3-х элементов, doc - dict, DOCS - глобальная переменная, list из doc'ов Как его можно перенести на C, чтобы подключить через ctypes? Как я понял, нужно создать класс, который наследует ctypes.Structure
class Doc(ctypes.Structure):
    _fields_ = [("path", ctypes.c_char_p),
                ("red", ctypes.c_int),
                ("green", ctypes.c_int),
                ("blue", ctypes.c_int)]
Позже сделать list
DOCS_STRUCTURE = Doc * len(DOCS)
Заполнить этот лист из DOCS и передать в функцию(dll) на C, но как передать структуру через ctypes я не знаю(в ctypes нет подходящего типа)Типы ctypes Делал подключение другой dll следующим образом
distance = ctypes.CDLL('myfib.dll').distance
distance.restype = ctypes.c_float
distance.argstypes = (ctypes.c_long,)
Какой C код необходимо написать? (Хотя бы набросок)
Набросал код на C и Python
#include <math.h>
#include <wchar.h>
#include <stdlib.h>
struct Doc
{
    wchar_t path[512];
    int r;
    int g;
    int b;
};
 
struct Docs
{
    struct Doc docs[1000000];
};
 
struct Color
{
    int r;
    int g;
    int b;
};
 
float distance(int a, int b, int c, int d, int e, int f)
{
    return sqrt((a-b)*(a-b)+(c-d)*(c-d)+(e-f)*(e-f));
}
 
struct Doc main(long len, struct Color c, struct Docs ds)
{
 
    long near = 1000000;
    long l;
    struct Doc f_d;
    for (l = 0; l < len; l++){
        struct Doc d = ds.docs[l];
        float dist = distance(c.r, d.r, c.g, d.g, c.b, d.b);
        if (dist < near){
            near = dist;
            f_d = d;
        };
    };
    return f_d;
 
};
class Doc(ctypes.Structure):
    _fields_ = [("path", ctypes.c_wchar_p),
                ("r", ctypes.c_int),
                ("g", ctypes.c_int),
                ("b", ctypes.c_int)]

class Docs(ctypes.Structure):
    _fields_ = [("docs", Doc * 1000000)]

class Color(ctypes.Structure):
    _fields_ = [("r", ctypes.c_int),
                ("g", ctypes.c_int),
                ("b", ctypes.c_int)]
Но при работе с функцией(непосредственно вызовом) выходит ошибка -1073741819 При запуске скомпилированного exe такая же ошибка.

Решение задачи: «Python, C и Ctypes»

textual
Листинг программы
#include <wchar.h>
 
struct Doc { wchar_t path[512]; int r; int g; int b; };
struct Color { int r; int g; int b; };
 
int nearest (int len, struct Color c, struct Doc *ds)
{
 
  double near = 1e12;
  int res= 0, i;
  for (i = 0; i < len; i++){
    double dist = (c.r-ds[i].r)*(c.r-ds[i].r) + (c.g-ds[i].g)*(c.g-ds[i].g)
        + (c.b-ds[i].b)*(c.b-ds[i].b);
    if (dist < near) {
      near = dist;
      res= i;
    }
  }
  return res;
}

Объяснение кода листинга программы

В данном коде представлен алгоритм поиска ближайшего цвета в массиве структур Doc. Структура Doc содержит путь к файлу (wchar_t path[512]) и значения красного, зеленого и синего цветовых каналов (int r, g, b). Структура Color также содержит значения красного, зеленого и синего цветовых каналов. Функция nearest принимает три аргумента: длину массива структур Doc (len), структуру Color (c) и указатель на массив структур Doc (ds). Внутри функции создаются две переменные: near - ближайшее расстояние до цвета в массиве ds и res - индекс этого цвета в массиве ds. Затем происходит цикл по всем элементам массива ds. Для каждого элемента вычисляется расстояние между цветами с помощью формулы euclidean distance (разница возводится в квадрат, затем суммируется). Если текущий элемент имеет меньшее расстояние, чем near, то обновляются значения near и res. После завершения цикла возвращается значение res, которое представляет собой индекс ближайшего цвета в массиве ds.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 4.5 из 5