我在尝试结合 C++ 和 C 代码时发现了奇怪的行为。我在 C 代码中使用 C++ 类,并使用 static_cast
和该类的 void*
。这是通过以下方式完成的。
//C++ code
void* newCSPI() {
return static_cast<void*>(new XSpi);
}
该函数在 header 中声明如下。
//C++ code
extern "C" void* newCSPI(void);
然后我可以在 C 代码中调用 C++ 函数。下面是其他功能的实现示例。
//C++ code
void selectCSlave(void* spi) {
static_cast<SPI*>(spi)->selectSlave();
}
此函数还在 header 中声明为 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*
,则您可以对此值执行的唯一转换是返回到您从其转换为 a 的特定类型 void*
(当然,您也可以将其转换为 char*
)。
所以当你这样做时:
return static_cast<void*>(new XSpi);
撤消该转换的唯一方法是将其转换为 XSpi*
。因此,你以后的 Actor 阵容:
static_cast<SPI*>(spi)->selectSlave();
这是非法的。
您可能想要做的是:
return static_cast<void*>(static_cast<SPI*>(new XSpi));
这将首先将其转换为基类(大概是 SPI
),然后将其转换为 void*
。
关于C++ 指针值随 static_cast 改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37548982/