I'm creating a library driver for AdaFruit's GFX library. During Constructor initialization, all the variables (set in another .cpp) are returned as zero. This code has several modular files to separate graphics functions from graphics primitives from device interfacing. What am I doing wrong?
In the Arduino sketch I call the class constructor: MB_GFX_SPI (in file MB_GFX_SPI.cpp). In the Constructor I'm call a function: mbR.SetMatrixSize (in another file raster.cpp). Also in the Constructor I call a function: clearScreen (in the same file MB_GFX_SPI.cpp).
The test variable mbR.r_totNumChannels set in clearScreen is returned with 99. All the variables set in mbR.SetMatrixSize return zero.
//Test Sketch
//Initialize both the Adafruit library and the current library.
//Instantiate an object mbGFX so all Adafruit GFX and MB_GFX add-on functions are addressed as mbGFX.xxx();
MB_GFX_SPI mbGFX = MB_GFX_SPI(Period, numCathodeLeds, numAnodeLeds, CathodeSSPin, AnodeSSPin);
//In file MB_GFX_SPI.cpp
MB_GFX_SPI::MB_GFX_SPI(int Period, int numCathodeLEDS, int numAnodeLEDS,
int CathodeSSPin, int AnodeSSPin)
: Adafruit_GFX(numCathodeLEDS, numAnodeLEDS) {
mbR.SetMatrixSize(numCathodeLEDS, numAnodeLEDS);
clearScreen(0);
}
void MB_GFX_SPI::clearScreen(uint16_t color) {
mbR.r_totNumChannels = 99; //test set value
}
//In file mb_raster.cpp
void mbRasterClass::SetMatrixSize(int numCathodeLeds, int numAnodeLeds){
//cathodes require 1 byte per channel
//anodes require 1 bit per channel
int numAnodeChannels = numAnodeLeds;
int numCathodeChannels = mbX.pin2pin * numCathodeLeds; //times 1 or 3
r_numCathodeRegisters = (int)((numCathodeChannels+7)/8); //select next higher number of registers
r_numCathodes = 8 * r_numCathodeRegisters; //must be whole 8 bit registers - is every single chatode pin
r_numAnodeRegisters = (numAnodeChannels+7)/8; //round up to next register number
r_numAnodes = 8 * r_numAnodeRegisters; //must be whole 8 bit registers
r_PWMBufferSize = r_totNumChannels = r_numAnodes * r_numCathodes;
r_PWMBuffer = (uint8_t *) realloc(r_PWMBuffer, r_totNumChannels); //resize array for PWMBuffer
}
1 Answer 1
First, I would do what Edgar Bonet suggested, call the normal constructor:
MB_GFX_SPI mbGFX (Period, numCathodeLeds, numAnodeLeds, CathodeSSPin, AnodeSSPin);
Second, I'm not keen on what you are doing in the constructor for a variable which appears to be at global scope (mbGFX).
See What's the "static initialization order fiasco"?
Basically you cannot assume that constructors in different compilation units are called in any defined sequence, you also cannot assume that the system has been initialized yet (ie. init()
called).
Thus, things that address the hardware (eg. clearScreen(0);
) may not work properly, or at all.
-
1thanks for additional suggestions. I've recently installed Visual Studio+Visual Micro and have been tracing the initialization process.user3511552– user35115522015年08月23日 14:36:25 +00:00Commented Aug 23, 2015 at 14:36
mbR
comes from.GFX_SPI mbGFX(...);
) instead of using copy-initialization (GFX_SPI mbGFX = MB_GFX_SPI(...);
).