1

我有一个具有这种结构的共享内存(参见代码片段 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;
...

正如您在评论中看到的那样,我知道哪个字节代表什么信息。无论如何,我将内存转换为结构(参见代码片段 2)。此结构中的属性当前是整数值。值 55 和 47 存储在前两个属性中。看起来,'00' 将被忽略,我无法逐字节读取整个内存。如何按字节读取内存?

代码片段 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 值(参见代码片段 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";
    ... 
4

4 回答 4

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)。

我建议您阅读有关序列化的信息。

于 2013-11-09T20:59:11.497 回答
3

您可能有混叠和对齐问题。阅读本文以了解更多详细信息:严格的混叠和对齐

基本上,可以将内存复制到本地结构中以避免此类问题:

Shm shmInfo;

memcpy(&shmInfo,&pBuf[shmInfoOffset],sizeof(shmInfo));
于 2013-11-09T21:04:03.827 回答
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); 
}

为此目的使用宏也不是一个坏主意。

于 2013-11-09T21:16:41.147 回答
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;
}
于 2013-11-09T21:38:24.550 回答