C++ 指针值随 static_cast 改变

标签 c pointers c++11

我在尝试结合 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);
}

0x000xFF 是正在写入的值。

最佳答案

如果您将指针强制转换为 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/

相关文章:

C指针赋值: wrong address and segmentation fault

c++ - 即使启用了 C++11,静态成员初始化也不适用于 GCC

c - strncpy 不能正确存储字符 C

c - 如何使用我的 pkcs#8 文件获取 ecdsa 字符串

c++ - 基于范围的 for 循环与 const shared_ptr<>

c - 为 3D 数组分配内存

c++ - 从源代码构建 GCC 5.4;如此构建的可执行文件尝试链接不兼容的 libstdc++ 并且无法运行

c++ - 用 0's if it' 填充 vector 而不是 8 的倍数

c - 在C中定义16位整数

c - 从C中的不同线程读取文件