【发布时间】:2016-05-31 14:50:48
【问题描述】:
我看到尝试结合 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 是正在写入的值。
【问题讨论】:
-
尚未阅读所有内容,但您可以为 typedef 使用不透明的结构定义,在您的实现中节省大量的转换。
-
请提供minimal reproducible example。此外,
void*的 typedef 确实令人困惑——尤其是当CSPI是void*但SPI实际上是某种类型时。 -
是什么让您认为价值发生了变化?你从调试器告诉?也许调试器显示了错误的东西。代码还能用吗?
-
@KABoissonneault 调试器确实显示了不同的值。指向的对象的所有属性也已更改,此时代码不再起作用。它在
static_cast调用期间被更改,因此在底层函数中是不同的和错误的。 -
deselectCSlave()中的代码是什么?当您使用调试器通过监视变量进入该函数时,您是否看到它发生变化的点?