结构体
这里的结构体指的是C/C++语言的结构体:就是一个buffer和各个变量的偏移。
结构体的字节对齐
这个大家都清楚,不清楚的就看看书吧,实在不想码字。
脚本描述的结构体转化为buffer
字节对齐:pack取值可以为1,2,4,8
根据变量的类型,分别计算各个变量的大小还有在对其字节后的偏移即可。
宿主语言的buffer根据脚本描述的结构体访问其中的变量
这一步离不开上面那一步。其实也都是根据脚本的描述计算各个变量的类型和偏移。
有时间我把和业务有关的代码删掉,把可运行的骨干框架代码打个zip发出来
代码片段如下:
#pragma once
#include <vector>
enum c_type
{
type_un,
type_handle,
type_i1,
type_i2,
type_i4,
type_i8,
type_ui1,
type_ui2,
type_ui4,
type_ui8,
type_sz,
type_wsz,
type_float,
type_double,
type_object,
type_char,
type_wchar,
type_byte,
type_struct,
};
extern c_type GetVariantCType(LPCSTR lpszType);
extern int GetCTypeLen(c_type type);
class varstream;
class _variant_;
class CTypeParamInfo
{
public:
CTypeParamInfo();
~CTypeParamInfo();
BOOL Parse(LPCSTR lpszType);
DWORD GetSize();
DWORD GetTypeLength();
//反序列化结构体转为kv对,返回字节数
int get_value(BYTE* pBits, DWORD dwBitsLen, std::tr1::shared_ptr<_variant_>& value);
//序列化为结构体buffer时使用,返回字节数
int write(varstream* stream, const std::tr1::shared_ptr<_variant_>& value) const;
protected:
int write_array(varstream* stream, const std::tr1::shared_ptr<_variant_>& value, std::vector<DWORD>::const_iterator& iter, std::vector<DWORD>::const_iterator& iter_end) const;
int write(varstream* stream, const std::tr1::shared_ptr<_variant_>& value, DWORD dwEleCount) const;
int get_value(BYTE* pBits, DWORD dwBitsLen, DWORD dwEleCount, std::tr1::shared_ptr<_variant_>& value);
int get_array_value(BYTE*& pBits, DWORD& dwBitsLen, std::tr1::shared_ptr<_variant_>& value, std::vector<DWORD>::const_iterator& iter, std::vector<DWORD>::const_iterator& iter_end);
protected:
c_type m_type;
std::vector<DWORD> m_vec_ele_count; //如果是数组,数组个数
};
#include "stdafx.h"
#include "type_parse.h"
#include "variant.h"
#include "varstream.h"
#include "varobject.h"
c_type GetVariantCType(LPCSTR lpszType)
{
ATLASSERT(lpszType != NULL);
#ifdef WIN32
if(_stricmp(lpszType, "handle") == 0)
return c_type::type_handle;
if(_stricmp(lpszType, "i1") == 0)
return c_type::type_ui1;
if(_stricmp(lpszType, "i2") == 0)
return c_type::type_i2;
if(_stricmp(lpszType, "i4") == 0)
return c_type::type_i4;
if(_stricmp(lpszType, "i8") == 0)
return c_type::type_i8;
if(_stricmp(lpszType, "ui1") == 0)
return c_type::type_ui1;
if(_stricmp(lpszType, "ui2") == 0)
return c_type::type_ui2;
if(_stricmp(lpszType, "ui4") == 0)
return c_type::type_ui4;
if(_stricmp(lpszType, "ui8") == 0)
return c_type::type_ui8;
if(_stricmp(lpszType, "sz") == 0)
return c_type::type_sz;
if(_stricmp(lpszType, "wsz") == 0)
return c_type::type_wsz;
if(_stricmp(lpszType, "float") == 0)
return c_type::type_float;
if(_stricmp(lpszType, "double") == 0)
return c_type::type_double;
if(_stricmp(lpszType, "char") == 0)
return c_type::type_char;
if(_stricmp(lpszType, "wchar") == 0)
return c_type::type_wchar;
if(_stricmp(lpszType, "byte") == 0)
return c_type::type_byte;
#else
ATLASSERT(FALSE);
#endif
return c_type::type_un;
}
int GetCTypeLen(c_type type)
{
ATLASSERT(type != type_object);
#ifdef WIN32
switch(type)
{
case type_i1:
case type_ui1:
case type_char:
case type_byte:
return 1;
case type_i2:
case type_ui2:
case type_wchar:
return 2;
case type_i4:
case type_ui4:
return 4;
case type_i8:
case type_ui8:
return 8;
case type_sz:
case type_wsz:
case type_handle:
case type_float:
return 4;
case type_double:
return 8;
}
#else
ATLASSERT(FALSE);
#endif
return 0;
}
//
//
// CTypeParamInfo
//
CTypeParamInfo::CTypeParamInfo()
{
}
CTypeParamInfo::~CTypeParamInfo()
{
}
BOOL CTypeParamInfo::Parse(LPCSTR lpszType)
{
ATLASSERT(lpszType != NULL);
m_type = GetVariantCType(lpszType);
if(m_type != c_type::type_un)
{
m_vec_ele_count.push_back(1);
}
else
{
//看看是不是数组
LPCSTR lpszSrc = lpszType;
LPCSTR lpsz = strchr(lpszSrc, '[');
if(lpsz)
{
CStringA strVarType;
strVarType.Append(lpszSrc, lpsz - lpszSrc);
m_type = GetVariantCType(strVarType);
if(m_type != c_type::type_un)
{
while (lpsz != NULL)
{
lpsz++;
LPCSTR lpszEnd = strchr(lpsz, ']');
if(lpszEnd)
{
m_vec_ele_count.push_back(atoi(lpsz));
lpszEnd++;
lpszSrc = lpszEnd;
lpsz = strchr(lpszSrc, '[');
}
}
}
}
}
return (m_type != c_type::type_un);
}
DWORD CTypeParamInfo::GetTypeLength()
{
return GetCTypeLen(m_type);
}
DWORD CTypeParamInfo::GetSize()
{
DWORD dwCount = 1;
std::vector<DWORD>::const_iterator iter = m_vec_ele_count.begin();
while (iter != m_vec_ele_count.end())
{
dwCount *= *iter;
iter++;
}
return (GetCTypeLen(m_type) * dwCount);
}
int CTypeParamInfo::write(varstream* stream, const std::tr1::shared_ptr<_variant_>& value) const
{
#ifdef WIN32
if(value->is_object())
{
//数组
std::vector<DWORD>::const_iterator iter = m_vec_ele_count.begin();
varobject* pobj = value->asObject();
if(pobj)
{
return write_array(stream, value, iter, m_vec_ele_count.end());
}
}
else
{
std::vector<DWORD>::const_iterator iter = m_vec_ele_count.begin();
ATLASSERT(iter != m_vec_ele_count.end());
if(iter != m_vec_ele_count.end())
return write(stream, value, *iter);
}
#else
ATLASSERT(FALSE);
#endif
return 0;
}
int CTypeParamInfo::write_array(varstream* stream, const std::tr1::shared_ptr<_variant_>& value, std::vector<DWORD>::const_iterator& iter, std::vector<DWORD>::const_iterator& iter_end) const
{
ATLASSERT(value->is_object());
varobject* pobj = value->asObject();
if(pobj)
{
DWORD dwSize = 0;
std::pair<std::tr1::shared_ptr<_variant_>, std::tr1::shared_ptr<_variant_>> kvPair;
size_t count = pobj->size();
ATLASSERT(count > 0 && count == *iter);
if(count > 0 && count == *iter)
{
BOOL bArray = FALSE;
kvPair = pobj->GetPair(0);
if(kvPair.second)
{
bArray = kvPair.second->is_object();
iter++;
}
DWORD dwElementCount = 1;
if(iter != iter_end)
dwElementCount = *iter;
for (int i =