如何将 volatile int** 转换为 void**

How to cast volatile int** to void**

我有这个旧的 C - 代码,我的编译器警告我(旧的 C 风格转换)。

volatile uint32_t* map;
void** argForSomeAPIfunction = (void**)↦

如何将其转换为 C++ 转换样式?我需要将 volatile uint32_t** 转换为 void**.

我需要这个的原因是有一个闭源供应商 API 希望我传递一个 void** 指针。我无法更改该函数签名。另一方面,供应商告诉我,我可以使用指向 uint32_t 的指针访问此寄存器映射,它们始终是 32 位的,并且他为我提供了 C 风格的工作示例,它使用 (void**)&。我尝试了这个 C 示例,它工作正常。

旁注:该供应商 API 通过自定义内核模块与 PCIe 卡通信。有两种选择,一种是使用使用“ioctl”和内置检查的安全 API 函数读取 PCIe 卡的内部存储器,另一种是使用对已初始化的 32 位寄存器映射的无监督访问通过调用 API::InitializeRegisterMap((void**)&map);。这只会在程序开始时执行一次。之后,我使用 map[offset] 直接访问内存,其中偏移量以 4 个字节为步长,而不是监督函数 API::ReadRegister(offset),后者在某些情况下速度较慢并且严重延迟数据采集(而卡正在做其他任务)。计算机不会更改寄存器内容,它只是读取那些内容。外置的独立卡可以随时改变寄存器内容,所以厂商的例子中引入了关键字volatile,我相信。

经过多次尝试和错误步骤后,我注意到这不能通过简单的转换步骤完成,您需要连接两个:

void** argForSomeAPIfunction = reinterpret_cast<void**>(const_cast<uint32_t**>(&map));

需要内部一个来摆脱易失性,第二个用于从 int 转换为 void。

如果这是为了初始化,那么我猜它的作用是 fill in a void *,而不是其他任何东西,也就是说,就像在 C++ 中一样void *&.

类型的参数

我相信它的目的是用作

void *ptr;
if (API::InitializeRegisterMap(&ptr)) {
    ...
}

然后之后你将取ptr中的值并将那个转换为 volatile uint32_t *map:

void *ptr;
volatile std::uint32_t *map;
if (API::InitializeRegisterMap(&ptr)) {
    map = static_cast<std::uint32_t *>(ptr);
}

最值得注意的是在C中,相对于C++,这可以写成completely castless,这应该被认为是一个好兆头。

此外,您想像避免瘟疫一样避免reinterpret_cast