C ++ arduino库返回具有错误值的整数数组

时间:2018-12-04 09:40:20

标签: c++ arduino

我目前正在使用C ++为Arduino写一个库,以从阅读器中获取8个字符的十六进制RFID字符串,并将该字符串转换为字节,将每两个字符视为一个字节的一部分,以使“ 1234ABCD”变为0X12、0X34 ,0XAB,0XCD。然后将这些字节转换为表示它们的整数值,以使先前的值分别变为18、52、171和205。然后,将这些整数放置在数组中并返回给调用方。因为RFID字符串是十六进制的,所以我将每对中第一个字符的整数值乘以16。

C ++库:

int AccessPortal::hexToInt(char character) {
  if(int(character) -  '0' < 10) {
    return int(character)  - '0';
  }
  else {
    if(isupper(character)) {
      return int(character) - '7';
    }
    else {
      return int(character) - 'W';
    }
  }
}

int* AccessPortal::getByteArray(std::string uid) {
  int byteArray[4];
  int intArray[8];
  int counter = 0;
  for(int i = 0; i < 8; i++) {
    if(i  % 2 == 0) {
      intArray[i] = hexToInt(uid[i]) * 16;
    }
    else {
      intArray[i] = hexToInt(uid[i]);
    }
  }
  for(int i = 1; i < 8; i = i + 2) {
    byteArray[counter] = intArray[i - 1]  + intArray[i];
    counter ++;
  }
  return byteArray;
}

Arduino代码:

 void setup() {
      // put your setup code here, to run once:
      AccessPortal access(); //constructor 
      int *h;
      h = access.getByteArray("1234ABCD");
      for(int i = 0; i < 4; i++) {
        Serial.println(h[i]);
      } 
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

但是,当我运行该程序时,以下内容会打印为串行:

1073741740
1073741680
1073670364
1075849820

这很奇怪,因为当我分别运行C ++库中的函数并将结果打印到终端时,值是正确的。我猜这意味着在Arduino代码中返回和/或访问数组的方式中发生了错误,但是我不确定。

1 个答案:

答案 0 :(得分:1)

正如其他人所说的那样,只要局部变量超出范围,指向局部变量的指针就会失效,因此不应返回。您可以改为创建一个ByteArray对象,该对象可以从函数中按值返回。使用ArduinoSTL的示例:

#include <ArduinoSTL.h>
#include <string>
#include <cstdlib>

struct ByteArray {
    uint32_t m_value;
    bool m_valid;

    // convert hex string to uint32_t value
    ByteArray(const std::string& uid) :
        m_value(std::strtoul(uid.c_str(), nullptr, 16)),
        m_valid(true)
    {
        if(uid.size()!=8) m_valid = false;
    }

    // converting assignment operator
    ByteArray& operator=(const std::string& uid) {
        m_value = std::strtoul(uid.c_str(), nullptr, 16);
        if(uid.size()==8) m_valid = true;
        else m_valid = false;
        return *this;
    }

    // subscript operator to access the individual bytes (as ints)
    int operator[](size_t x) const {
        if(x>3) return -1;
        return (m_value>>((3-x)*8))&0xFF;
    }
};

struct AccessPortal {
    // change the getByteArray signature to this
    ByteArray getByteArray(const std::string&);
};

ByteArray AccessPortal::getByteArray(const std::string& uid) {
    // return by value - copy elision
    return ByteArray(uid);
}

void setup() {
    AccessPortal access; //default constructing
    ByteArray h = access.getByteArray("1234ABCD");

    Serial.println(h.m_value); // dec: 305441741  hex: 1234ABCD

    for(int i = 0; i < 4; i++) {
        Serial.println(h[i]); // dec: 18, 52, 171, 205  hex: 12, 34, AB, CD
    }
}

void loop() {
    //
}