Я хочу перенести небольшую библиотеку, написанную на C с Python C API, в чистую библиотеку/приложение C. В конце концов, я хочу, чтобы это работало на C++, но я думал, что он лучше работает, не зависимо от python, прежде чем сосредоточиться на том, чтобы получить его на C++.Проблема с портированием библиотеки Python C на «чистую» C
Это кусок кода, который я хочу, чтобы порт: https://github.com/adafruit/Adafruit_DotStar_Pi/blob/master/dotstar.c
Это контролирует определенный тип светодиодов над SPI. На практике можно управлять многими тысячами светодиодов с помощью этой части кода. Он отлично работает в Python, но мой портированный код для приложения C просто ничего не делает, как только я выхожу за пределы 256 светодиодов. С ниже 256 светодиодов все работает нормально.
Поэтому мне кажется, что проблема с типом или распределением, по какой-то причине, не вызывает нарушения доступа к памяти. Мое тестовое приложение не падает, светодиоды просто ничего не делают, когда выходят за порог 256.
У меня есть два фрагмента кода, где я просто не уверен на 100%, что делал Python, что я заменил своим лучшим образованным предположением.
Все данные для светодиодов хранятся в структуре DotStarObject, поэтому я подозреваю, что проблема связана с этой структурой.
Во-первых, я удалил макрос PyObject_HEAD из структуры DotStarObject, насколько я понимаю, все это добавляет некоторые вещи, которые Python необходимо внутренне.
Далее я изменил способ распределения структуры при вызове функции DotStar_new.
Во-первых, я изменил тип функции от static PyObject *DotStar_new
до static DotStarObject *DotStar_new
, когда он возвращает указатель на структуру DotStarObject.
Виновник, который, как мне кажется, вызывает мою ошибку, является частью, где структура заполнена данными. Обычно Python выделяет здесь некоторую память. Насколько я понял Pythons tp_alloc
все, что он делает, выделяет память размера используемого типа (в этом случае DotStarObject).
Так что это:
PyTypeObject *type;
DotStarObject *self = NULL;
(...)
// Allocate space for LED data:
if((!n_pixels) || ((pixels = (uint8_t *)malloc(n_pixels * 4)))) {
if((self = (DotStarObject *)type->tp_alloc(type, 0))) {
self->numLEDs = n_pixels;
self->dataMask = 0;
self->clockMask = 0;
self->bitrate = bitrate;
self->fd = -1;
self->pixels = pixels; // NULL if 0 pixels
self->pBuf = NULL; // alloc'd on 1st use
self->dataPin = dPin;
self->clockPin = cPin;
self->brightness = 0;
self->rOffset = rOffset;
self->gOffset = gOffset;
self->bOffset = bOffset;
Py_INCREF(self);
} else if(pixels) {
free(pixels);
}
}
стал этим (пока отсутствует гарантию при выделении для self
терпит неудачу):
DotStarObject *self = (DotStarObject*)malloc(sizeof(DotStarObject));
(...)
if((!n_pixels) || ((pixels = (uint8_t *)malloc(n_pixels * 4)))) {
self->numLEDs = n_pixels;
self->dataMask = 0;
self->clockMask = 0;
self->bitrate = bitrate;
self->fd = -1;
self->pixels = pixels; // NULL if 0 pixels
self->pBuf = NULL; // alloc'd on 1st use
self->dataPin = dPin;
self->clockPin = cPin;
self->brightness = 0;
self->rOffset = rOffset;
self->gOffset = gOffset;
self->bOffset = bOffset;
}
ли я неправильно, что (DotStarObject *)type->tp_alloc(type, 0)
делал или я substitue правильно с DotStarObject *self = (DotStarObject*)malloc(sizeof(DotStarObject));
?
Мой полный код можно найти здесь, если я пропустил некоторые cruical информацию: http://pastebin.com/xddN9JMs
Нет языка «C/C++»! Только два ** разных ** языка C и C++, поэтому просить «чистый C/C++» бесполезно. – Olaf
Это действительно сбивает с толку. Я изменил название. Я только добавил C++, потому что там, где я хочу идти, но я думаю, это не важно для вопроса. Я знаю, что это разные языки. – PTS
Если вы будете использовать Ruby-код, если хотите действительно код Brainfuck, нет, это не имеет значения. В противном случае это очень хорошо. Задайте вопрос, который хотите использовать, и используйте для этого соответствующий код. – Olaf