Skip to main content
GameDev.net gamedev.net
🔒 Locked

how to typecast a char * to std::vector

Started by yamaki308 Apr 27, 2008 at 6:27 AM 6 replies 2.1k views
Original Post
yamaki308
yamaki308
I'm trying to send a std::vector of two elements to the client using the winsock sendto() function like so:

// it's a seeking message. send a reply now
CMessageHosting msgHost;
int iCMHostSize = 0;
static std::vector<CMessageHosting> cmHostList;
					
msgHost.SetUsername(phUsername);
msgHost.SetHostname(phHostname);
msgHost.SetNumClients((unsigned)pClientList->size());
	
cmHostList.push_back(msgHost);
	
iCMHostSize = (int)cmHostList.size() * sizeof(CMessageHosting);
					
std::cout<<"Receiving a seek from "<<
((CMessageSeeking*)pCMsg)->GetUsername()<<
"@"<<GetHostDescription(rSockAddr)<<std::endl;
			
// send the host response back to the sender
result = sendto(rSocket, (char *)&cmHostList, iCMHostSize,
		0, (const sockaddr *)&rSockAddr, nSALen);
									
if(result == SOCKET_ERROR)
   CheckWSAError("sending a replay to a seek");
else
   bDone = true;


what I want is to get the vector of two elements to the client like so:

while(!bStop)
{
    char receiveMsg[MAX_MESSAGE_LEN] = {0};
				
    iResult = recvfrom(hClientSocket, receiveMsg, MAX_MESSAGE_LEN, 0,
			(sockaddr *)&saFrom, &iFromLen);
								  
    if(iResult == SOCKET_ERROR)
	CheckWSAError(" recvfrom ");
    else
    {
	//CMessage *pMsg = (CMessage *)receiveMsg;
	std::vector<CMessage*> *cmList = 0;
					
	cmList = (std::vector<CMessage*> *)receiveMsg;
					
	bUpdateDisplay = SeekMessageHosts(&hostList, cmList,
				nID, dwLoopTime, saFrom);
	bStop = true;
   }
}

Is the way to typecast a char * to std::vector?
Molle85
Molle85
You can't just typecast a vector since the elements are dynamically allocated when you push back... try Serializing
http://en.wikipedia.org/wiki/Serialization
yamaki308
yamaki308
I'll try it. thanks.
Trillian
Trillian
We'll need the code of your CMessage class and maybe the prototype of the SeekMessageHosts function in order to be able to help you. You might still be able to adapt the following to your needs :

std::vector<CMessage*> messages;while(!bStop){    char receptionBuffer[MAX_MESSAGE_LEN] = {0};				    iResult = recvfrom(hClientSocket, receptionBuffer, MAX_MESSAGE_LEN, 0,			(sockaddr *)&saFrom, &iFromLen);								      if(iResult == SOCKET_ERROR)	CheckWSAError(" recvfrom ");    else    {	messages.push_back(new CMessage(receptionBuffer, iFromLen));		bUpdateDisplay = SeekMessageHosts(&hostList, &messages,				nID, dwLoopTime, saFrom);	bStop = true;   }}// Don't forget to delete the elements of the message vector. Better yet, use smart pointers!

yamaki308
yamaki308
CMessage class
class CMessage{	public:		CMessage(void)		{			strcpy(msgMarker, MESSAGE_MARKER);		        memset(strUsername, 0, MAX_USERNAME_STRLEN * sizeof(char));		}		virtual ~CMessage(void){}				void SetUsername(const char*pUsername)		{ strcpy(strUsername, pUsername);}					char *GetUsername(void) { return strUsername; }		MESSAGE_ID GetMsgID(void) { return msgID; }		char *GetMsgMarker(void) { return msgMarker; }				protected:			MESSAGE_ID msgID;		char msgMarker[sizeof(MESSAGE_MARKER)];		char strUsername[MAX_USERNAME_STRLEN];};


SeekMessageHosts function prototype
bool SeekMessageHosts(std::vector<SHost> *pHostList, 		      std::vector<CMessage *> *pcMsgList,		      unsigned &rID, const DWORD &rLoopTime,		      const SOCKADDR_IN &rSockAddr);
Kylotan
Kylotan
Your problem is that you're passing a pointer to the host list. That's not where the data is stored. cmHostList is indeed a vector that contains the data you want, but that doesn't mean the data you want to send is stored at the address &cmHostList. Think about it: that vector could contain other data members, such as size or something. It will also hold a pointer to where the data really is, so that it can resize that buffer.

If you pass in &cmHostList[0], then you are giving the address of the first member of the vector, which is the start of the actual data you want. If I remember correctly, the original C++ standard doesn't necessarily require that a vector stores its data contiguously like an array, but in practice it is always the case as far as I know.

This just moves the problem one level though; if the data in the vector is not plain-old-data, ie. if your CMessageHosting objects contain more than just simple data types, then this method will still fail because those objects will be written out incorrectly. This is why serialisation in C++ can be complex and you can't easily use the old C-style 'pass a pointer and hope' methods for sending data around.
yahastu
yahastu
Quote:
Original post by Kylotan
If you pass in &cmHostList[0], then you are giving the address of the first member of the vector, which is the start of the actual data you want. If I remember correctly, the original C++ standard doesn't necessarily require that a vector stores its data contiguously like an array, but in practice it is always the case as far as I know.


It is guaranteed to be contiguous

SiCrane
SiCrane
As of 2003 anyways. In the original 1998 version of the C++ Standard it wasn't.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.