自定义脚本引擎开发纪实 - 结构体

本文介绍了自定义脚本引擎中结构体的字节对齐原理,详细讲解了如何将脚本描述的结构体转化为buffer,并在宿主语言中根据结构体描述访问变量。提到了利用C/C++的pack特性处理字节对齐,并预告将分享无业务代码的骨干框架。
摘要由CSDN通过智能技术生成

结构体

这里的结构体指的是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 = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值