Click here to Skip to main content
Licence CPOL
First Posted 25 Sep 2008
Views 8,102
Downloads 31
Bookmarked 9 times

Dynamic Structures

By | 30 Mar 2010 | Article
allocates a memory filled with the variable with appropriate padding

Source Code

Introduction  

When writing some network application we need to pass data in the form of byte array. that data we get from simply typecasting the  data pointer to the byte array and then we can send this over the network. This seems simple when working fully in the c/c++ environment but when it comes to com object where you have too few datatypes to choose from then it becomes a monumental task.  

Here I present a technique to build the structure format at run time

Background  

The basis of my code of aligning variables in to the memory to form a particular structure is based on padding rule which the microsoft compiler applies.

Rule 1. The size of the structure is in multiple of size of largest native data type available in the structure e.g. (in char, int and short  int is of the largest size) 

Rule 2. The structure member variable of native datatype will be at the offset which is in multiple of the size of the datatype  

Rule 3. In case of embedded structure, the offset will be in the multiple of size of largest native data type available in the embedded structure  

Using the code  

The main function of aligning the variables in to memory goes as following

STDMETHODIMP CDynamicStructures::GetCharArray(VARIANT *pVarIn, long nSize, VARIANT *pVarOut)
{
	//Get the maximum size of native variable present in the list of input
	DWORD maxSize = GetMaxSize(pVarIn, nSize);
	//some thing wrong was present in the variant array
	if(maxSize == (DWORD)-1)	//Return Failure
		return S_FALSE;

	std::string str;
	//Allocate some initial size to string
	//increase it if necessary
	str.resize(maxSize * 100, '\0');

	DWORD dwSizeAllocated = 0;
	for(int i = 0; i < nSize; ++i)
	{
		DWORD size = GetSize(pVarIn[i]);
		int offset = dwSizeAllocated % size;
		//Apply Padding Rule. 2
		dwSizeAllocated += offset ? (size - offset) : 0;

		if(pVarIn[i].vt == VT_BSTR)	//Special case of string
		{
			std::string strData = (char *)_bstr_t(pVarIn[i]);
			int length = strData.size() + 1;
			memcpy((char*)str.c_str() + dwSizeAllocated, strData.c_str(), length);
			dwSizeAllocated += length;
		}
		else if(pVarIn[i].vt == VT_ARRAY)	//Special case of embedded structure
		{
			memcpy((char*)str.c_str() + dwSizeAllocated, pVarIn[i].parray->pvData, 
						pVarIn[i].parray->rgsabound[0].cElements);
			dwSizeAllocated += pVarIn[i].parray->rgsabound[0].cElements;
		}
		else
		{
			memcpy((char*)str.c_str() + dwSizeAllocated, &(pVarIn[i].bVal), size);
			dwSizeAllocated += size;
		}
	}

	//Apply Padding Rule. 1
	int offset = dwSizeAllocated % maxSize;
	dwSizeAllocated += offset ? (maxSize - offset) : 0;

	//Fill the value in array
	//Create safe array of 1 dimension 
	SAFEARRAY FAR* ppsa;
	unsigned int ndim =  1;
	//Allocate descriptor
	SafeArrayAllocDescriptor(ndim, &ppsa);

	(ppsa)->rgsabound[0].lLbound = maxSize;	//For internal purpose
	//this maxSize information will be used when embedding structures
	//in other structures
	(ppsa)->rgsabound[0].cElements = dwSizeAllocated;
	(ppsa)->cbElements = sizeof(char);
	
	//Allocate memory for the data
	SafeArrayAllocData(ppsa);
	memcpy(ppsa->pvData, str.c_str(), dwSizeAllocated);
	
	pVarOut->vt = VT_ARRAY;
	pVarOut->parray = ppsa;
	//Return Success
	return S_OK;
}

I have done the testing of my code with vbscript.  

'Create Object
Set DynamicStructure = WScript.CreateObject("DynamicStructure.DynamicStructures")

'Create a structre of uchar, int, string of 45 characters, double, ushort
Dim data(5)
data(0) = DynamicStructure.GetUChar(5)
data(1) = DynamicStructure.GetInt(56)
data(2) = "hellohellohellohellohellohellohellohellohello"
data(3) = DynamicStructure.GetDouble(7.3452345)
data(4) = DynamicStructure.GetUShort(2345)

'create another structure of uchar, int, instance of previous structure,
'another instance of previous structure, string of 45 characters, double,
'ushort

Dim data1(7)
data1(0) = DynamicStructure.GetUChar(5)
data1(1) = DynamicStructure.GetInt(56)
data1(2) = DynamicStructure.GetCharArray(data(0), 5)
data1(3) = DynamicStructure.GetCharArray(data(0), 5)
data1(4) = "hellohellohellohellohellohellohellohellohello"
data1(5) = DynamicStructure.GetDouble(7.3452345)
data1(6) = DynamicStructure.GetUShort(2345)

'Allocate memory of for the structure by passing the array pointer and size of
'the array
dynSt3 = DynamicStructure.GetCharArray(data1(0), 7)
'Use the structure in whatever way you like
DynamicStructure.UseStructure dynSt3

'Release the memory
DynamicStructure.ReleaseCharArray dynSt3
DynamicStructure.ReleaseCharArray data1(2)
DynamicStructure.ReleaseCharArray data1(3)


Set DynamicStructure  = Nothing  

Points of Interest 

I was getting runtime error in vbscript when assigning the variable returned by GetCharArray to another variable. so i directly used the variable without making a copy of that. Currently in search of fix to this problem

For more information visit http://techxperts.info

History

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

rahulagarwal33

Software Developer
Applied Research Internation
India India

Member

B. Tech + M. Tech in Chemical Engineering Smile | :) from IIT Delhi

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 1 PinmemberSledgeHammer0110:07 30 Mar '10  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 30 Mar 2010
Article Copyright 2008 by rahulagarwal33
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid