我看到奇怪的行为试图结合C ++和C代码。我在C代码中使用C ++类,使用static_cast
和void*
来上课。这是通过以下方式完成的。
//C++ code
void* newCSPI() {
return static_cast<void*>(new XSpi);
}
此函数在标头中声明如下。
//C++ code
extern "C" void* newCSPI(void);
然后我可以在C代码中调用C ++函数。其他功能的实现示例如下所示。
//C++ code
void selectCSlave(void* spi) {
static_cast<SPI*>(spi)->selectSlave();
}
此函数在标题中也声明为extern "C"
。
该铸造功能如下实现。
//C++ code
void SPI::selectSlave(void) {
// Select the slave by setting the slave select to low
XGpio_DiscreteWrite(&slaveSelectDevice, 1, 0x00);
}
我正在尝试执行以下代码块。这一切都取得了成功,除了最后一行。
//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);
在第二次transferC(spi)
调用期间,指针以某种方式改变了值。在强制转换函数内部,指针仍具有相同的值。在它投射到的函数内部,值会发生变化。实现与第一个transferC(spi)
完全相同,它确实有效。这两个调用之间没有代码。
我不明白为什么价值会突然改变。我在这里错过了什么?
deselectCSlave()
和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
和0xFF
是正在写的价值观。
如果你将指针强制转换为void*
,那么你唯一允许对此值进行的转换就会回到你转换为void*
的特定类型(好吧,你也可以将它转换为char*
)。
所以当你这样做时:
return static_cast<void*>(new XSpi);
你可以撤消该演员阵营的唯一方法是将其投射到XSpi*
。因此,你以后的演员:
static_cast<SPI*>(spi)->selectSlave();
那是违法的。
你可能想做的是:
return static_cast<void*>(static_cast<SPI*>(new XSpi));
这将首先将其转换为基类(大概是SPI
),然后将其转换为void*
。