[英]An efficient way to convert ByteData in Dart to unsigned char* in C++?
[英]What is the best way to convert an unsigned long to char* in C++
我需要通过套接字发送一些unsigned long
。 由于unsigned long
为4字节,因此接收方仅期望4字节。 我编写的转换函数可以在下面找到,但仅当必须存储在char中的数字不大于127时才可以。 0x7F。 对于大于0x7f的值,我希望扩展的ASCII表( http://www.asciitable.com/ )中的字符将存储在char中,但是绝对不是这种情况。 例如,对于0x90,不存储任何内容。 我正在将VS12与Unicode字符集一起使用。
有什么想法可以使转换正确吗?
void number2char(unsigned long number, char* nrAsByte){
std::stringstream numberSS;
numberSS << std::hex << number;
int length = numberSS.str().length();
length = length / 2.0 + 0.5;
nrAsByte = new char[sizeof(number)]();
std::fill(nrAsByte, nrAsByte + length, '\x20');
while (length > 0){
int lastTwo = (number & 0xff);
number >>= 8;
unsigned char a = lastTwo; // this doesn't work if lastTwo > 0x7F
std::memcpy(nrAsByte + length - 1, &a, 1);
--length;
}
}
我为代码感到抱歉,它没有经过我的良好测试,并且包含错误,请不要使用它,而是遵循答案中的建议
为什么不这样:
void number2char(unsigned long number, char* nrAsByte){
unsigned char *dst= reinterpret_cast<unsigned char *> nrAsByte;
for (int i=0; i<sizeof(unsigned long); ++i) {
*dst++= number & 0xFF;
number >>= 8;
}
}
嗯,我一直在玩弄安东尼奥的答案,因为它感觉并不完整和正确,最后我得到的结果比我预期的还要复杂,但是有时它的目的是复杂性。
下面的代码还手动完成了htonl
/ ntohl
的转换(可能是相反的字节序,因此不希望将其与htonl
混合使用,要么使用它,要么用htonl
重写它)。
与Antonio的来源不同,当输入数字类型为8字节长时(在我的测试平台上unsigned long
为8字节-BTW,尝试吗?!),它不会覆盖内存,它将截断该值以适合所需的网络字符*缓冲。
我试图对其进行广泛评论,以使您在每个决定中增加进一步的复杂性(在基本上使用unsigned int number
用作(char *)(&number)
,该想法也可以提供,但不能保护字节序,并且可能会终止如果您混合使用不同的长度类型,则在覆盖内存中)。 但是,如果您看到不清楚的地方,请问任何事情。
#include <iostream>
#include <string>
// Experiment with different types to see differences
// (and how data are truncated when sizeof number > sizeof networkdata)
//typedef unsigned int numberType_t;
typedef unsigned long numberType_t; // on my platform this is 8 bytes long
constexpr int networkBytesSize = 4; // number of chars to be sent trough network with (char *)
// define network data type:
// used "struct" to make sizeof(networkData_t) return actual number of bytes
typedef struct {
unsigned char d[networkBytesSize];
char *cptr() { return reinterpret_cast<char *>(d); }
} networkData_t;
// Writes number into network char* buffer nrAsByte, endianness agnostic
void number2char(numberType_t number, networkData_t & nrAsByte) {
for (size_t i = 0; i < sizeof(networkData_t); ++i) {
nrAsByte.d[i] = number & 0xFF;
number >>= 8;
}
}
// Read number back from network char* buffer
numberType_t char2number(const networkData_t & nrAsByte) {
numberType_t number = 0;
size_t i = sizeof(networkData_t);
while (i--) number = (number<<8) | nrAsByte.d[i];
return number;
}
int main()
{
printf("numberType_t size in bytes: %lu, networkData_t size in bytes: %lu\nAll following numbers are hex:\n",
sizeof(numberType_t), sizeof(networkData_t));
numberType_t number = numberType_t(0x9ABCDEF0123456FEul);
std::cout << "source number: " << std::hex << number << std::endl;
// Write number into char buffer
networkData_t networkData;
number2char(number, networkData);
std::cout << "network bytes:";
for (size_t i = 0; i < sizeof(networkData_t); ++i) std::cout << " [" << unsigned(networkData.d[i]) << "]";
std::cout << std::endl;
// Test usability of (char *) pointer access
const char * testCharPtrConversion = networkData.cptr();
printf("as char * (decimal signed): %d %d ...\n", testCharPtrConversion[0], testCharPtrConversion[1]);
// Read number from char buffer
number = char2number(networkData);
std::cout << "read number: 0x" << std::hex << number << std::endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.