C ++ pointer value changes with static_cast

I see strange behavior trying to combine C ++ and C code. I am using a C ++ class in C code using static_cast with void* for the class. This is done as follows.

 //C++ code void* newCSPI() { return static_cast<void*>(new XSpi); } 

This function is declared in the header as follows.

 //C++ code extern "C" void* newCSPI(void); 

Then I can call the C ++ functions in the C code. An example of the implementation of other functions is given below.

 //C++ code void selectCSlave(void* spi) { static_cast<SPI*>(spi)->selectSlave(); } 

This function is also declared as extern "C" in the header.

This casting function is implemented as follows.

 //C++ code void SPI::selectSlave(void) { // Select the slave by setting the slave select to low XGpio_DiscreteWrite(&slaveSelectDevice, 1, 0x00); } 

I am trying to execute the following block of code. All this is successful, except for the last line.

 //C code void* spi = newCSPI(); /* Select device. */ selectCSlave(spi); /* Transfer data over SPI*/ transferC(spi, MOSI, MISO, ByteNum); // It breaks here // /* Transfer data over SPI*/ transferC(spi, MOSI, MISO, ByteNum); /* Un-select device. */ deselectCSlave(spi); 

During the second call to transferC(spi) pointer somehow changes the value. Inside the translation function, the pointer still has the same meaning. Inside the function that it distinguishes, the value changes. The implementation is exactly the same as the first transferC(spi) , which works. There is no code between these two calls.

I do not understand why the meaning will suddenly change. What am I missing here?

Code deselectCSlave() and SPI::deselectSlave(void) :

 void deselectCSlave(void* Cspi) { static_cast<SPI*>(Cspi)->deselectSlave(); } void SPI::deselectSlave(void) { // Deselects the slave by setting the slave select to high XGpio_DiscreteWrite(&slaveSelectDevice, 1, 0xFF); } 

0x00 and 0xFF are the values ​​that are written.

0
source share
1 answer

If you pointed to void* , the only conversion you are allowed to do for this value returns to the specific type from which you converted to void* (well, you can also pass it to char* ).

So when you do this:

 return static_cast<void*>(new XSpi); 

The only way you can undo this tide is to distinguish it from XSpi* . Therefore your later selection:

 static_cast<SPI*>(spi)->selectSlave(); 

It's illegal.

What you probably want to do is the following:

 return static_cast<void*>(static_cast<SPI*>(new XSpi)); 

This first converts it to a base class (presumably SPI ) and then converts it to void* .

+2
source

All Articles