C ++指针值随static_cast而改变 [英] C++ Pointer value changes with static_cast
问题描述
我看到一些奇怪的行为试图结合C ++和C代码。我在C代码中使用C ++类,使用 static_cast
和类中的 void *
。这是通过以下方式完成的。
I'm seeing weird behavior trying to combine C++ and C code. I'm using a C++ class within C code, using static_cast
with a void*
to the class. This is done in the following way.
//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);
然后我可以在C代码中调用C ++函数。下面是其他函数的实现示例。
I can then call the C++ functions in the C code. An example of the implementation of the other functions is seen below.
//C++ code
void selectCSlave(void* spi) {
static_cast<SPI*>(spi)->selectSlave();
}
此函数也声明为 externC
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'm trying to execute the following block of code. It all succeeds except for the very 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);
在第二个 transferC(spi)
,指针以某种方式改变值。在cast函数内,指针仍然具有相同的值。在函数内部转换,值改变。实现与第一个 transferC(spi)
完全相同,它工作。这两个调用之间没有代码。
During the second transferC(spi)
call, the pointer somehow changes value. Inside the cast function, the pointer still has the same value. Inside the function it is cast to, the value changes. The implementation is exactly the same as the first transferC(spi)
, which does work. There is no code in between those 2 calls.
我看不到为什么值会突然改变。
I can't see why the value would suddenly change. What am I missing here?
编辑:
添加了 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 *
)。
If you cast a pointer to void*
, the only conversion you're allowed to do to this value is back to the specific type from which you converted to a void*
(well, you can also cast it to a char*
).
所以当你这样做:
return static_cast<void*>(new XSpi);
您可以撤销该投射的唯一方法是将其投射到 XSpi *
。因此,您之后的转换:
The only way you can undo that cast is by casting it to XSpi*
. Therefore, your later cast:
static_cast<SPI*>(spi)->selectSlave();
这是非法的。
想要做的是这样的:
return static_cast<void*>(static_cast<SPI*>(new XSpi));
这将首先将其转换为基类(可能 SPI
),然后将其转换为 void *
。
That will first convert it to the base class (presumably SPI
), then convert it to void*
.
这篇关于C ++指针值随static_cast而改变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!