将内存地址分配给指针

时间:2018-12-10 20:59:43

标签: c++ pointers driver

我试图将一个内存地址分配给一个指针,但是无法使其编译。 该地址是一个内存映射的硬件寄存器。

#include <memory>

template<void* Address>
struct ClassAImpl {
    uint64_t* Register = reinterpret_cast<uint64_t*>(Address);
};

uint8_t arrA[10] = { 1, 2, 3, 4 };
using ClassA1 = ClassAImpl<(void*)&arrA>;       // error: the address of the 'void' subobject of 'arrA' is not a valid template argument
using ClassA2 = ClassAImpl<0x8767876787678767>; // error: could not convert template argument '9756915996444559207' from 'long unsigned int' to 'void*'


template<uint64_t Address>
struct ClassBImpl {
    uint64_t* Register = reinterpret_cast<uint64_t*>(Address);
};

uint8_t arrB[10] = { 1, 2, 3, 4 };
using ClassB1 = ClassBImpl<(void*)&arrB>;       // error: conversion from 'void*' to 'long unsigned int' in a converted constant expression       
using ClassB2 = ClassBImpl<0x8767876787678767>; // This compiles.

我想同时使用指向缓冲区的指针和ClassA2使用固定地址。

我正在使用Gcc 8.2编译C ++

2 个答案:

答案 0 :(得分:0)

我不知道您要达到什么目的,但是您陷入非类型模板参数的奇怪行为。非类型模板参数不能用临时实例化。来自https://en.cppreference.com/w/cpp/language/template_parameters

  

“对于指向对象的指针,模板参数必须指定   具有静态存储持续时间的完整对象的地址和   链接(内部或外部),或一个常量表达式   计算为适当的空指针或std :: nullptr_t值。”

using ClassA1 = ClassAImpl<(void*)&arrA>; - temporary
using ClassA2 = ClassAImpl<0x8767876787678767>; - template argument is constant expression, template parameter is pointer to void, doesn't make any sense
using ClassB1 = ClassBImpl<(void*)&arrB>; - temporary
using ClassB2 = ClassBImpl<0x8767876787678767>; - constant expression which can be used as template parameter uint64_t

答案 1 :(得分:0)

也许您想要类似的东西:

#include <stdint.h>

uint64_t (&hw_regs)[10] = *reinterpret_cast<uint64_t(*)[10]>(0xdeadbeefUL);
uint64_t &hw_reg0 = hw_regs[0];

根据需要制作引用的对象volatile。如果您询问要用脚射击自己的子弹的正确口径,那么您就会知道自己在做什么。标准的[expr.reinterpret.cast]部分允许进行此强制转换,但是当然,引用不是安全地得出的。