将Python C库移植到";纯粹的;C
我想将一个用C编写的带有Python C API的小型库移植到一个纯C库/应用程序。最后,我希望这能在C++中工作,但我认为最好在没有把它放到C++中之前就不用Python依赖来工作。 这是我要移植的代码片段: 这通过SPI控制特定类型的LED。实际上,使用这段代码可以控制数千个LED。它在Python中工作得很好,但是我将代码移植到C应用程序中,只要超过256个LED,它就什么也做不了。低于256个LED,一切正常 所以在我看来,这要么是类型问题,要么是分配问题,出于某种原因,不会导致内存访问冲突。我的测试应用程序没有崩溃,当超过256阈值时,LED根本不做任何事情 我有两段代码,我不能100%确定Python在做什么,我用我受过最好教育的猜测代替了它们 LED的所有数据都存储在一个名为DotStarObject的结构中,因此我怀疑问题与此结构有关 首先,我从DotStarObject结构中删除了PyObject_HEAD宏,据我所知,这只是添加了一些Python内部需要的东西 接下来,我改变了调用DotStar_新函数时分配结构的方式 首先,我将函数类型从将Python C库移植到";纯粹的;C,python,c,pointers,struct,spi,Python,C,Pointers,Struct,Spi,我想将一个用C编写的带有Python C API的小型库移植到一个纯C库/应用程序。最后,我希望这能在C++中工作,但我认为最好在没有把它放到C++中之前就不用Python依赖来工作。 这是我要移植的代码片段: 这通过SPI控制特定类型的LED。实际上,使用这段代码可以控制数千个LED。它在Python中工作得很好,但是我将代码移植到C应用程序中,只要超过256个LED,它就什么也做不了。低于256个LED,一切正常 所以在我看来,这要么是类型问题,要么是分配问题,出于某种原因,不会导致内存访问
static PyObject*DotStar\u new
更改为static DotStarObject*DotStar\u new
,因为它返回指向DotStarObject结构的指针
我认为导致我的错误的罪魁祸首是结构中充满数据的部分。通常Python会在这里分配一些内存。据我所知,Pythonstp_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*)type->tp_alloc(type,0)
正在做的事情,或者我是否正确地用DotStarObject*self=(DotStarObject*)malloc(sizeof(DotStarObject))代码>
如果我遗漏了一些基本信息,可以在这里找到我的完整代码:有一件事我会怀疑这个循环:
for (uint8_t i = 0; i < dotty->numLEDs; ++i){
// setPixelColor(dotty,i,r,g,b);
setPixelColor(dotty,i,r,0,0);
}
(uint8\u t i=0;inumLEDs;++i)的{
//setPixelColor(点、i、r、g、b);
setPixelColor(dotty,i,r,0,0);
}
索引使用的是8位类型,不管dotty->numLEDs的值是多少,它只允许256个值。
没有语言“C/C++”!只有两种不同的语言C和C++,所以要求“纯C/C++”是没有用的,这确实令人困惑。我改了标题。我只添加了C++,因为这是我想去的地方,但我想这对这个问题并不重要。我知道这是不同的语言。如果你想使用Ruby代码,那就使用Brainfuck代码吧,不,没关系。否则它会很好地发挥作用。询问你想使用的问题,并使用适当的代码。我的意思是,在这里提到C++是不重要的。我在这里选择C,我希望现在已经清楚了。哦,这是事实上非常令人震惊的。我不确定这是在我遇到问题之前还是之后发生的,因为我经常更改测试代码。它可能只是最近才添加的,而且与此无关,但我会检查并报告/接受答案。我觉得自己非常愚蠢。这确实是问题所在。非常感谢您这么快就发现了这一点!
for (uint8_t i = 0; i < dotty->numLEDs; ++i){
// setPixelColor(dotty,i,r,g,b);
setPixelColor(dotty,i,r,0,0);
}