我有一个这种结构的共享内存(参见codesnippet 1),所有值都是十六进制值:
Position 00: 55; // memory overall, byte 00 to 03;
Position 01: 00;
Position 02: 00;
Position 03: 00;
Position 04: 47; // memory for header information, byte 04 to 07;
Position 05: 00
Position 06: 00;
Position 07: 00;
Position 08: 00; // version, byte 08, 09;
Position 09: 00;
Position 0A: 64; // rate of refreshing memory between processes
Position 0B: 00;
Position 0C: 00;
Position 0D: 00;
Position 0E: 00;
Position 0F: 4L;
...
正如您在评论中所看到的,我知道哪个字节代表什么信息。无论如何,我把内存放在一个结构中(参见codesnippet 2)。此结构中的属性当前是整数值。值55和47存储在前两个属性中。看起来,'00'将被忽略,我无法逐字节读取整个存储器。如何按字节读取内存?
codesnippet 2:
struct Shm {
int memorySize; // size of memory space; min 4 bytes, Position 00 - 03; ie 55 is a hex value and means 84
int headerSize; // size of header space; min 4 bytes, Position 04 - 07; ie 47 (hex), so 71 (dec) same number as config-dialog
int byte3; // version number
int byte4; // refreshing interval in msec
...
然而,在内存中有一些区域,包含一些字符 - 如何将这些字节值转换为字符并创建它们的单词,目前我只能转换为int值(参见codesnippet 3)
int main(void){
std::cout << "*** Start SharedMemory ***\n";
HANDLE hMapFile;
...
Shm * pBuf = (Shm *) MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
std::cout << " Debug memorySize " << ": " << dec << pBuf->memorySize << " (dec); " << hex << pBuf->memorySize << " (hex); " << &pBuf->memorySize << " (Adresse);\n"; // 84 Bytes
std::cout << " Debug headerSize " << ": " << dec << pBuf->headerSize << " (dec); << hex << pBuf->headerSize << " (hex);\n"; // 71 Bytes
std::cout << " Debug byte3 " << ": " << dec << pBuf->byte3 << " (dec); " << hex << pBuf->byte3 << " (hex);\n";
...
答案 0 :(得分:3)
备注:将文件转换为struct是个坏主意。对齐,int的大小,endian可以在不同的系统中有所不同。
投射到文件的任何部分:
const char * pBuf = (const char *) MapViewOfFile...
const Mytype * myVar = (const Mytype *)(pBuf + myVarOffset);
因此对于字符串,只需向pBuf添加偏移量(pBuf + myVarOffset - 就是您所需要的全部内容) - 然后您将获得指向字符串的开始指针。 (希望文件中字符串末尾有一个零字节。)
如果您的结构应该有一个具有未指定长度的缓冲区/字符串变量,则以下代码可能有所帮助:
struct MyStruct
{
int size_of_string;
char my_string[1]; //can be used as a long string of size size_of_string
};
请注意,在这种情况下,sizeof(MyStruct)不会为您提供正确的值,因此您无法使用“new”和堆栈分配此对象(请改用malloc / free)。
我建议你阅读有关序列化的内容。
答案 1 :(得分:2)
您可能遇到别名和对齐问题。请阅读此内容以获取更多详细信息:strict aliasing and alignment
基本上,可以将内存复制到本地结构中以避免此类问题:
Shm shmInfo;
memcpy(&shmInfo,&pBuf[shmInfoOffset],sizeof(shmInfo));
答案 2 :(得分:1)
如果处理二进制数据,最好编写这样的函数:
char getByte(char* data,int offset);
void setByte(char* data,int offset,char value);
char getWord(char* data,int offset);
...
void setLongword(char* ptr,int value);
然后你可以创建使你的代码变得漂亮和可读的函数:
int getVersion(char* data) {
return (int)getByte(data,8);
}
为此目的使用宏也不是一个坏主意。
答案 3 :(得分:1)
如果你的字符包含4个字节到一个int中,那么下面的例子可能有所帮助。请注意,必须考虑结束性。
#include <string>
#include <iostream>
void appendCharsFromInt(std::string& inString, int intAsChars, int charCount)
{
char someChars[4];
memcpy(someChars, &intAsChars, sizeof(int));
inString.append(someChars, charCount);
}
int _tmain(int argc, _TCHAR* argv[])
{
int byte0 = 0x6c6c6548;
int byte1 = 0x6f57206f;
int byte2 = 0x00646c72;
std::string completeString;
appendCharsFromInt(completeString, byte0, 4);
appendCharsFromInt(completeString, byte1, 4);
appendCharsFromInt(completeString, byte2, 4);
std::cout << completeString << std::endl;
return 0;
}