C++ MemoryStream

January 17th, 2010

When you have a file read into memory, and would like to use std::istream to access it, you have a couple of ways to do this. The obvious one is to create a std::stringstream from that memory location. It works fine, but it has a side effect of copying the data into its own buffer:

int main()
{
	char text[] = "Some text string";

	// this creates a copy of 'text' for std::stringstream
	std::string data(text);

	// this creates a reader that will use the copy of data
	std::stringstream reader(data);
}

With large files this adds unnecessary overhead. So what is the “right” way to do this? I came up with something like that:

class membuf : public std::basic_streambuf<char>
{
public:
	membuf(char* p, size_t n) {
		setg(p, p, p + n);
	}
}

int main()
{
	char text[] = "Some text string";

	// this creates a stream buffer at a given memory location
	membuf buffer(text, sizeof(text));

	// this creates an istream using the above buffer
	std::istream reader(&mb);
}

Pretty simple and effective. And does not use anything but STL.

How to rename a C++ thread in Visual Studio 2008 debugger?

January 10th, 2010

Sometimes it’s useful to rename your threads so you can find them easily in your Visual Studio debugger. In .NET-land it’s easy: you have to set the System.Threading.Thread.Name property of the thread you wish to rename and you’re done. It’s not that simple with native code, though.

For native code, when Visual Studio (and WinDbg) is attached, it listens for a specific exception being raised, with specific information in it.

struct VS_THREADNAME_INFO
{
	DWORD type;
	LPCSTR name;
	DWORD threadId;
	DWORD flags;
};

void SetThreadName(DWORD threadId, LPCSTR name)
{
	if (IsDebuggerPresent())
	{
		VS_THREADNAME_INFO tni = { 0x1000, name, threadId, 0 };

		__try
		{
			size_t s = sizeof(VS_THREADNAME_INFO) / sizeof(DWORD);
			RaiseException(0x406D1388, 0, s, (DWORD*)&tni);
		}
		__except (EXCEPTION_CONTINUE_EXECUTION) { /* do nothing */ }
	}
}

The code above should be pretty self-explanatory. Source: Setting a Thread Name (Unmanaged)