>

포인터의 값이 0x0224와 같은 메모리 주소이므로 어떻게하면 리터럴로 주어진 주소를 포인터에 할당 할 수 있습니까? 정수 리터럴을 포인터에 할당하려고 시도했지만 추측 할 수 있듯이 실제로 제대로 작동하지 않았습니다.

  • 답변 # 1

    간단한 reinterpret_cast 로 이것을 할 수 있습니다

    auto ptr = reinterpret_cast<void*>(0x123);
    
    

  • 답변 # 2

    심장 내용에 절대적으로이를 수행 할 수 있습니다. 프로세스의 메모리 공간을 분리하는 운영 체제는 프로세스의 할당 된 메모리 공간 외부의 메모리에 액세스하려고하면 일반적으로 프로그램을 종료하지만 할당하는 값이 프로세스에 액세스 할 수있는 값이면 읽고 쓰기 (일부 추가 제한이 적용될 수 있음)

    의견에서 지적한 바와 같이, 질문은 실제로 그러한 과제를 수행하는방법을 언급 할 수도있다. 이것은 다른 답변에서 잘 설명됩니다. 짧은 대답은 리터럴을 적절한 유형의 포인터 값으로 캐스트해야한다는 것입니다.

  • 답변 # 3

    Since the value of a pointer is a memory address, like 0x0224, can you somehow assign an address given as a literal to a pointer?

    데스크탑에 대한 대답은 '아니요'라고 생각합니다.

    사용자 프로세스에서 포인터의 값은 가상 메모리 주소입니다. 주소는 사실상 존재하므로 실제 메모리에 매핑되지만 실제 주소는 나타내지 않습니다. 특히 실제 앱의 실행마다 실제 주소가 다를 수 있습니다.

    따라서 컴파일 타임에 사용하기 위해 반복 가능한 리터럴을 생성 할 특정 주소를 발견하는 방법이 문제 일 수 있습니다. 다음에 실행할 때 어떤 (? 가상) 메모리에 액세스 할 수 있는지 어떻게 알 수 있습니까?

    데스크톱에서는 할 수 없다고 생각합니다.

    <시간>

    그래서 통신 업계에서 작동하는 임베디드 시스템의 예를 들어 보겠습니다. 코드가 실제 메모리 매핑 된 장치에 액세스 할 때 질문에서 제안하는 내용과 관련이 있다고 생각합니다.

    여기서 mcu라고하는 선반 컴퓨터 수준으로 건너 뜁니다.

    MCU에는 여러 개의 논리 장치가 있습니다. 이 스 니펫에서는 pci2 (가장 먼저 찾은 것)를 무작위로 선택합니다

    class mcu_pci2_t  // all reg's 32 bit
    {
      public:
         mcu_pci2_t(void){};
         ~mcu_pci2_t(void){/*always implement*/};
      enum MCU_PCI2_CONSTRAINTS
      {         
         MCU_PCI2_ADDR     = 0x80000000LU,                 // 0x8000 0000
         //
         ...
         //
         MC_SRBL_FPGA_ADDR = MCU_PCI2_ADDR + 0x08000000LU, // 0x8800 0000
         //
         MC_PCI2_CONSTRAINTS_END
      };
    
    

    다음으로 MC_SRBL_FPGA_ADDR을 자세히 살펴 보겠습니다. mcu의 하드웨어 로직은 주소 0x8000,0000LU에서 시작하고 SRBL은 0x8800,0000에서 시작합니다. 이 항목들도 많이 제거했습니다.

    enum MC_SRBL_CONSTRAINTS
    {
       CRXX_LED_ADDR            = MC_SRBL_FPGA_ADDR + 0x00000004, // 0x8100 0004 red,off        Bit0
    ...
       //
       FAN_LMPTEST_ADDR         = MC_SRBL_FPGA_ADDR + 0x00000040, // 0x8800 0040 normal/test    Bit0
       //
    ...
    //
    
    

    이제 코드에서 FAN_LMPTEST_ADDR을 사용하는 방법으로 건너 뜁니다.

    class fan_lmptest_t
    {
    public: 
       fan_lmptest_t(void){};
       ~fan_lmptest_t(void){/*always implement*/};
       // returns 0 when successful
       const char* change(bool on,   bool sim=false);
       uint32_t value(void) { uint32_t ret_val = reg(); return(ret_val); };
    private:
       inline vuint32_t& reg(void) { 
          return(*(reinterpret_cast<vuint32_t*>(FAN_LMPTEST_ADDR))); 
       };
    private: // coding standard: when not used, make NOT accessible AND do NOT implement
       fan_lmptest_t(const fan_lmptest_t&);            // copy constructor    X(const X&)
       fan_lmptest_t& operator= (const fan_lmptest_t&);// copy assignment     X& operator= (const X&)
    };
    
    

    여기서 우리는 enum 물리 주소 값이 포인터로 캐스팅 된 것을 볼 수 있습니다

    reinterpret_cast<vuint32_t*>(FAN_LMPTEST_ADDR);
    
    

    이 경우, vuint32_t는이 주소의 데이터를 "휘발성 uint32_t"로 처리하도록 컴파일러에 명령되었음을 의미합니다.

    (fyi-change () 메소드는 다른 곳의 .cc 파일에 구현되어 있습니다.)

    작동 적으로 램프 테스트를 활성화 또는 비활성화하기로 결정한 사용자 인터페이스 코드는이 코드와 약간 거리가 있습니다. 전체 팬을 켜거나 끕니다. 분명히 팬은 램프 테스트의 일부입니다. 모두 좋습니다.

    이것은 당신의 질문에서 제안하는 것과 매우 흡사합니다 ... 리터럴 (즉, 열거 형)은 실제 주소로 캐스팅 될 수 있으며 주소가 하드웨어에 올바르게 매핑되면 유레카! 우리에게는 팬이 있습니다.

    <시간>

    FYI-임베디드 운영 체제는 ONEA의 OSE입니다. MCU는 일부 ppc 파생물을 기반으로하므로 어느 것을 기억하지 마십시오. 하드웨어 매핑 메모리는 전용 32 비트 너비 hw 버스를 사용하지만 코드와 스택 및 힙은 적절한 캐시와 64 비트 너비 버스와 함께 드램 메모리에 상주합니다.

관련 자료

  • 이전 express - nodejs 웹앱을 호스팅하는 방법?
  • 다음 javascript - 탐색 막대 전환 단추에 축소 된 요소가 표시되지 않습니다