如何将 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
。
我有这个旧的 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
。