December 31st, 2008
admin

Apparently Windows 7 Beta has been leaked. Set for release in mid January of 09 a torrent was posted within’ the last week or 2 that contains the full unlocked beta.
You can find a blurb about the download here. You’ll also find the links to the torrents on said page. I recommend using the Mininova link as the Demonoid link seems to be down.
December 17th, 2008
admin
There are a plethora of articles on how to mix managed and unmanaged code. The problem I found is that none of them really discuss how to pass anything more than simple values from managed to unmanaged code. Or they explain how to marshal managed text strings to an unmanaged char * pointer. Here are a few related links:
Tutorial 1
Tutorial 2
MSDN Tutorials
What I want to discuss is how to directly pass pointer to a class and be able to call that classes functions from unmanaged code. You can find my example in the SVN repository under the name ‘MixedTest’
First things first, start a new project:
1.) Open Visual studio 2005
2.) Go to File->New-> Project
3.) In the ‘Project Types’ box click ‘Visual C++’
4.) In the ‘Templates Box’ select ‘Windows Forms Application’
5.) Done. Alternatively you can simply snag my example.
Next make up a quick and gritty gui. I’m not going to go over those steps. For this example we are going to pass the MouseEventArgs from our managed form class to our unmanaged Foo class. My gui contains a ‘Panel’ with the ‘MouseOver’ event.
Unmanaged Code (Foo.h)
#pragma once
#include <vcclr.h>
#include "DbgConsole.h"
class Foo
{
public:
Foo(void);
~Foo(void);
void MouseMove(gcroot<System::Windows::Forms::MouseEventArgs^> e);
};
Unmanaged Code (Foo.cpp)
#include "StdAfx.h"
#include "Foo.h"
Foo::Foo(void)
{
}
Foo::~Foo(void)
{
}
void Foo::MouseMove(gcroot<System::Windows::Forms::MouseEventArgs^> e){
gcroot<System::Windows::Forms::MessageBox^> *msg = new gcroot<System::Windows::Forms::MessageBox^>;
if(e->Button == System::Windows::Forms::MouseButtons::Left) {
(*msg)->Show("Mouse Move["+e->Location.X.ToString() +"," + e->Location.Y.ToString() + "]: Left Button Down");
}
}
and from our managed code(Form1.h)”
#include "Foo.h"
public ref class Form1 : public System::Windows::Forms::Form {
public:
Form1(void)
{
InitializeComponent();
_foo = new Foo;
}
private: Foo *_foo;
//.... other class specific stuff
private: System::Void panel1_MouseMove(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {
_foo->MouseMove(e);
}
};
gcroot is a life saver. Otherwise you have to take the time to manually cast variables back and forth. gcroot handles it all, automatically. The only problem is that the header is finicky. Depending on where it, can cause some extremely odd errors. I recommend including as the very first line of any file that needing gcroot.
Notice how we pass the MouseEventArgs directly to Foo, an unmanaged class? This saves us from having to pass each and every call to specific foo function although you could do that too.
If you create your own project from this post I recommend you at least take a look at my example in the repository. Every mouse movement will be recorded when the left mouse button is down and it is over our panel. Please note, each one of these will generate a text box. In my example code I also include a very simplistic Console debugger that actually uses a Windows Form and Textbox to create a fake shell. It only takes output but whatever.
December 11th, 2008
admin
Have you ever taken a good look at the resolution of the Windows Sleep(int milliseconds) and Time() functions? I mean really taken a look. Recently (within the last year) I was asked to write a logging function with 1 millisecond or better accuracy that didn’t hog the CPU. Easy right, just use a simple sleep(0) or sleep(1) to free up the thread so it doesn’t hog all the CPU and then use the c++ function time() to get the duration since the last logging event.
What I didn’t realize is that the built in time function has a max accuracy of 5-15 milliseconds depending, I assume, on the hardware. I don’t honestly know where the error lay as it was different on 4 of the 5 XP machines I tested. What is a guy to do?
Write a better timer:
#pragma once
#include <windows.h>
#ifdef _TIMER_USE_MACROS
#define TIMER_BEGIN(NAME) arcTimer NAME;\
NAME.Start(); \
double NAME##d1, NAME##d2;
#define TIMER_BEFORE(NAME) NAME.Stop();\
NAME##d1 = NAME.GetDurationInSecs();
#define TIMER_AFTER(NAME) NAME.Stop();\
NAME##d2 = NAME.GetDurationInSecs();
#define TIMER_OUTPUT(NAME) printf("Delay of %s timer: %f\n",#NAME,NAME##d2-NAME##d1);
#define TIMER_OUTPUT_MSG(NAME,MSG) log_errors("%s: %f\n",#MSG,NAME##d2-NAME##d1);
#define TIMER_GET(NAME) (NAME##d2-NAME##d1)
#define TIMER_CLASS_INIT(NAME) arcTimer NAME;\
double NAME##d1, NAME##d2;
#define TIMER_CLASS_START(NAME) NAME.Start();
#else
#define TIMER_BEGIN(NAME)
#define TIMER_BEFORE(NAME)
#define TIMER_AFTER(NAME)
#define TIMER_OUTPUT(NAME)
#endif
struct arcTimer {
void Start(void) {
//Make sure we are using a single core on a dual core machine, otherwise timings will be off.
DWORD_PTR threadAffMask = SetThreadAffinityMask(GetCurrentThread(), 1);
if(!QueryPerformanceFrequency(&ticksPerSecond))printf("Hires timer freq. not supported\n");
if(!QueryPerformanceCounter(&tick))printf("Hires timer counter not supported\n");
SetThreadAffinityMask(GetCurrentThread(),threadAffMask );
};
void Tick(void) {
//Make sure we are using a single core on a dual core machine, otherwise timings will be off.
DWORD_PTR threadAffMask = SetThreadAffinityMask(GetCurrentThread(), 1);
if(!QueryPerformanceCounter(&tock))printf("Hires timer counter not supported\n");
SetThreadAffinityMask(GetCurrentThread(),threadAffMask );
};
double GetDurationInSecs(void)
{
double duration = (double)(tock.QuadPart-tick.QuadPart)/(double)ticksPerSecond.QuadPart;
return duration;
}
LARGE_INTEGER ticksPerSecond;
LARGE_INTEGER tick; // A point in time
LARGE_INTEGER tock;
LARGE_INTEGER time; // For converting tick into real time
};
Instead of using Time() we directly query the performance frequency and counter of the CPU. This is a ridiculously accurate measurement. But Jeremy, “why are we setting a process affinity”, you might ask.
If your PC has more than 1 unique CPU core you need to specific processor affinity.
QueryPerformanceCounter() is not core specific. That is, you can’t guarantee which core it will use to get the performance counter. If our first ‘Tick’ event uses core 0 and the second tick uses core 1 we can’t trust the result as 2 cores can have different results. By specifying the use of the first CPU core only we avoid the problem completely. The documentation claims switching affinity mid program can cause slowdown. So far I’ve not seen any although occasionally there is a spike in the timer (~5ms) that may or may not be due to this.
Example Usage:
arcTimer time;
time.start();
time.tick();
double dLastTime = time.GetDurationInSecs();
//... do something
time.tick();
double dNewTime = time.GetDurationInSecs();
printf("Duration: %f\n",dNewTime - dLastTime);
Viola. So what does this have to do with Sleep()? Well after writing this class I noticed that any sleep value under 15 milliseconds (excluding 0 milliseconds) results in Sleep waiting from 5-15 milliseconds. I can only assume certain systems offer a better resolution timer internally. I’ve tested this on 5 different XP machines and each machine has a different time for Sleep(1).
Honestly I don’t know how to solve this problem. Unless you use a Sleep(1) or higher the program will hog the cpu. Yes sleep(0) releases the CPU but this doesn’t mean the program won’t still be hogging all the processing time. So unfortunately you are stuck with either running Sleep(0) at 100% cpu utilization or Sleep(1) which may have anywhere from 5-15 milliseconds in delay.

A few of my friends asked me what the logo on my blog depicts:
I wanted something that encompasses what I do for a living. I work with 3D models all day long so I took a manikin head scan and used a geodesic surfacer to create the colors. To put it another way, I wrote a piece of code that finds the distance from 1 point to every other point on the surface. The seed point being the tip of the nose in yellow. Colors range from yellow (closest) to purple (farthest). Distance is relative to the surface topology.
I needed to expand that image across the top of the blog so I thought a nice gradient would blend it together. Lastly the jigsaw puzzle. Everything we do is a puzzle and, in the case of this blog, each post reflects something that has shaped me both professionally and personally…. yes even videos about salads.
Oh and the title, I straight jacked it from KMDFM (Keine Mehrheit Für Die Mitleid or “no pity for the majority” in English.)