C ++指针值随static_cast而改变 [英] C++ Pointer value changes with static_cast

查看:165
本文介绍了C ++指针值随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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆