我看到奇怪的行为试图结合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
是正在写的值。
答案 0 :(得分:3)
如果您将指针转换为void*
,则您允许对此值进行的唯一转换将返回特定类型,您将转换为{{1} (好吧,你也可以把它投射到void*
)。
所以当你这样做时:
char*
您可以撤消该演员表的唯一方法是将其投放到return static_cast<void*>(new XSpi);
。因此,你以后的演员:
XSpi*
这是非法的。
您可能想要做的是:
static_cast<SPI*>(spi)->selectSlave();
首先将其转换为基类(大概是return static_cast<void*>(static_cast<SPI*>(new XSpi));
),然后将其转换为SPI
。