我目前正在使用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代码中返回和/或访问数组的方式中发生了错误,但是我不确定。
答案 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() {
//
}