typedef struct tagMBLIMAGEHEADER

DWORD               FileSize;  
DWORD               SrcSizeInPixel;
long                SrcWidthInPixel;
long                SrcHeightInPixel;
ImgRect             ImgArea;    //这也是结构体,定义见上面
WORD                MidTierNum; 
WORD                BitCount; 
WORD                RgbTableSize;                
TierHeaStruList     TierHeaList; //CList链表定义见上面
}MBLIMAGEHEADER;
以下是ImgRect和TierHeaStruList的定义:
typedef struct tagImgRect{
POINT  LefDowCoordinate;
POINT  RigTopCoordinate;
}ImgRect;typedef struct tagTierHeadStru{
DWORD  TierOffset;
DWORD  Resolution;
}TierHeaStru;typedef CList<TierHeaStru, TierHeaStru&>  TierHeaStruList;

解决方案 »

  1.   

    TierHeaStruList里元素的个数可以计算出来。请问大家上面的结果体如何计算他的大小阿?
      

  2.   

    如果是MBLIMAGEHEADER则不好说因为TierHeaStruList这个大小未知,得看CList的实现
      

  3.   

    但是我里面有链表阿,这个能用sizeof吗?我要把这样的结构体存到磁盘上,然后要知道写完后,写下面数据时的偏移量是多少。我是不是要用sizeof(MBLIMAGEHEADER)+链表里面元素个数*大小??所以有点搞不清楚请教下大家。谢谢了
      

  4.   

    这个TierHeaStruList里的元素个数, 在定义的时候不知道,但是在写数据之前是可以知道的。因为我要计算整个文件大小,还有计算写数据时候的偏移量
      

  5.   

    sizeof(MBLIMAGEHEADER)+sizeof(TierHeaStruList)吗?写到磁盘上就是这么大吗?
      

  6.   

    因为那个对其原则蛮麻烦的,除了每个元素的开始偏移必须为自己大小的整数倍以外,整个结构体的大小还必须是里面最大元素的整数倍。我里面包含ImgRect这个结构体,他的大小是16个字节,那是不是MBLIMAGEHEADER的大小必须是ImgRect的整数倍阿。
      

  7.   

    看你怎么写的?要写哪些数据。如果是只写TierHeaStruList的话那大小就是
    sizeof(TierHeaStruList),但它的成员变量所指向的内存块的数据都未写到文件里。
      

  8.   

    就是整个结构体包含的内容,包括链表里面的,都要写到磁盘上写到磁盘上也是按对其原则的吗?也就是我计算磁盘上文件大小的时候,也是用sizeof去计算吗?
      

  9.   

    写哪些数据就累加哪些数据,类和结构用sizeof判断其大小。
      

  10.   

    那意思就是在磁盘上也会填充无效的字节咯?
    我是用的内存映射文件写数据,所以我直接用的是memcpy写数据因为在TierHeaStruList里的数据在内存里肯定不是连续的,所有我把这个结构体里包含的数据,包括CList里面的,都重新拷到一段连续的内存里面。然后用这段内存的地址作为memcpy的源地址,内存映射返回的地址作为目标地址,就是这个大小,不知道该怎么计算??
      

  11.   

    sizeof(MBLIMAGEHEADER)+sizeof(TierHeaStru)*TierHeaStruList.GetCount()- sizeof(TierHeaStruList)
      

  12.   

    chehw(chehw)大哥,您有来给小弟捧场啦,谢谢啦!!我也感觉应该像你这样计算,但是就是不敢确定,感觉心里没底!!我还想问一下就是,内存映射文件把数据写到磁盘上后,系统在内存中填充的无效字节,会去掉吗?
      

  13.   

    如果你认为磁盘文件的末尾有无效数据,占用了额外的磁盘空间,可在CloseHandler(hMapFile)后,用SetFilePointer移到指定位置,再用SetEndOfFile结束就可以了。
      

  14.   

    typedef struct tagMBLIMAGEHEADER

    DWORD               FileSize;  
    DWORD               SrcSizeInPixel;
    long                SrcWidthInPixel;
    long                SrcHeightInPixel;
    ImgRect             ImgArea;    //这也是结构体,定义见上面
    WORD                MidTierNum; 
    WORD                BitCount; 
    WORD                RgbTableSize;                
    TierHeaStruList     TierHeaList; //CList链表定义见上面
    }MBLIMAGEHEADER;
    以下是ImgRect和TierHeaStruList的定义:
    typedef struct tagImgRect{
    POINT  LefDowCoordinate;
    POINT  RigTopCoordinate;
    }ImgRect;typedef struct tagTierHeadStru{
    DWORD  TierOffset;
    DWORD  Resolution;
    }TierHeaStru;typedef CList<TierHeaStru, TierHeaStru&>  TierHeaStruList;----------------------------------------------------------------------------sizeof是编译的时候确定大小,与CList中容纳了多少个节点数量无关。sizeof( MBLIMAGEHEADER ) 我不明白你这样的sizeof究竟能用来干什么?要copymemory复制数据吗?
      

  15.   

    chehw(chehw) 我指的是结构体在内存里对齐的时候,如果起始地址不是写入数据字节数的整数倍,系统将会自动填充,直到起始地址是整数倍。 我想问的是写入文件后,还是不是满足对齐的原则,系统填充的字节,还在不在?你上面说的用SetFilePointer然后用SetEndOfFile, 意思是不是创建内存映射对象的时候,创建得大一点, 然后将多余的空间截取掉?  这样的话,我也要知道前面写了多少数据啊,这个大小怎么算 ?
      

  16.   

    这取决于你写入文件的方式。
    例如:
    struct
    {
      short a;
    }T;
    T data;
    假设按4个字节对齐,设sizeof(T)=4如果你写入文件时用的是WriteFile(hFile, &data, sizeof(data), ...);则写入4个字节,会将系统填充字节写入。
    如果写入文件时用的是WriteFile(hFile, &data.a, sizeof(data.a),...); 则只写入2个字节。如果存储空间足够,一般不用考虑此类问题,只要保证写数据的方式与读数据的方式一致就可以了。
      

  17.   

    假设你写到 MBLIMAGEHEADER 的最后一项,TierHeaStruList对象。typedef CList<TierHeaStru, TierHeaStru&>  TierHeaStruList;CList内部存储的是一堆的指针,你保存这样的指针有意义吗?
      

  18.   

    template<class TYPE, class ARG_TYPE = const TYPE&>
    class CList : public CObject
    {
    protected:
    struct CNode
    {
    CNode* pNext;
    CNode* pPrev;
    TYPE data;
    };
    public:
    // Construction
    /* explicit */ CList(INT_PTR nBlockSize = 10);// Attributes (head and tail)
    // count of elements
    INT_PTR GetCount() const;
    INT_PTR GetSize() const;
    BOOL IsEmpty() const; // peek at head or tail
    TYPE& GetHead();
    const TYPE& GetHead() const;
    TYPE& GetTail();
    const TYPE& GetTail() const;// Operations
    // get head or tail (and remove it) - don't call on empty list !
    TYPE RemoveHead();
    TYPE RemoveTail(); // add before head or after tail
    POSITION AddHead(ARG_TYPE newElement);
    POSITION AddTail(ARG_TYPE newElement); // add another list of elements before head or after tail
    void AddHead(CList* pNewList);
    void AddTail(CList* pNewList); // remove all elements
    void RemoveAll(); // iteration
    POSITION GetHeadPosition() const;
    POSITION GetTailPosition() const;
    TYPE& GetNext(POSITION& rPosition); // return *Position++
    const TYPE& GetNext(POSITION& rPosition) const; // return *Position++
    TYPE& GetPrev(POSITION& rPosition); // return *Position--
    const TYPE& GetPrev(POSITION& rPosition) const; // return *Position-- // getting/modifying an element at a given position
    TYPE& GetAt(POSITION position);
    const TYPE& GetAt(POSITION position) const;
    void SetAt(POSITION pos, ARG_TYPE newElement);
    void RemoveAt(POSITION position); // inserting before or after a given position
    POSITION InsertBefore(POSITION position, ARG_TYPE newElement);
    POSITION InsertAfter(POSITION position, ARG_TYPE newElement); // helper functions (note: O(n) speed)
    POSITION Find(ARG_TYPE searchValue, POSITION startAfter = NULL) const;
    // defaults to starting at the HEAD, return NULL if not found
    POSITION FindIndex(INT_PTR nIndex) const;
    // get the 'nIndex'th element (may return NULL)// Implementation
    protected:
    CNode* m_pNodeHead;
    CNode* m_pNodeTail;
    INT_PTR m_nCount;
    CNode* m_pNodeFree;
    struct CPlex* m_pBlocks;
    INT_PTR m_nBlockSize; CNode* NewNode(CNode*, CNode*);
    void FreeNode(CNode*);public:
    ~CList();
    void Serialize(CArchive&);
    #ifdef _DEBUG
    void Dump(CDumpContext&) const;
    void AssertValid() const;
    #endif
    };
      

  19.   

    我觉得把一个类实例的东西变成char流的想法是愚蠢的。
      

  20.   

    我知道CList里面保存元素的内存是不连续的,所以我在写数据的时候, 是重新申请一块内存,这块内存的大小我也是通过这个结构体计算的。然后我在把这个结构体里所有的元素(包括Clist里面的)都拷到这块内存里面,然后再将新申请的并把数据拷过来的内存写到文件里。就因为这个结构体有多大,我不知道怎么计算,所以我对我现在分配的内存的大小比较怀疑,所以才发帖请教一下大家.
      

  21.   

    不好意思啊,我是新手,还有很多不懂,还请大家多多指教!那大哥能不能告诉我一种方法,我想把这个结构体里的所有元素包括Clist里面的元素,写到文件里,该用什么方法阿?还要能保证能从文件把这个结构体读出来。
      

  22.   

    TaiJi1985(太极_实践是检验真理的唯一标准,请没有试过的人保持沉默) ( ) 信誉:100    Blog  2007-1-25 12:06:27  得分: 0  
       
    重新映射到内存后,应该不会把它填充进去。指针变了。填进去也没意思。
    写个序列化,和反序列化的函数。自己处理比较好,而且升空间。=================================================================================== 你没有看仔细这个方案吗?
      

  23.   

    struct全整成class,不要再用struct来进行思考。