C++/CLI ref class using a win32 thread
-
05-07-2019 - |
Question
I'm trying to encapsulate some older win32 code in a C++/CLI ref class to make it better accessible from .NET code. This class needs to start a Win32 thread and pass a pointer to the class as a thread parameter. The code looks something like this:
ref class MmePlayer
{
int StartPlayback()
{
hPlayThread = CreateThread(NULL, 0, PlayThread, this, 0, &PlayThreadId);
}
};
static DWORD WINAPI PlayThread(LPVOID pThreadParam)
{
// Get a pointer to the object that started the thread
MmePlayer^ Me = pThreadParam;
}
The thread really needs to be a Win32 thread because it receives messages from the MME subsystem. I've tried wrapping the PlayThread function pointer in an interior_ptr, but the compiler wouldn't allow that. Also, I've tried to make the thread function a class method, but the compiler does not allow the _stdcall modifier on ref class methods. Do you know of a way to handle this?
Solution
Managed classes are passed around using 'handles' instead of references. You can't treat a handle to a managed class like a pointer. What you're going to want to do is create a native helper class that holds a handle to the managed class. Then you pass a pointer to the native helper into the thread start function. Like this:
#include <msclr/auto_gcroot.h>
using msclr::auto_gcroot;
ref class MmePlayer;
class MmeHelper
{
auto_gcroot<MmePlayer^> myPlayer;
};
ref class MmePlayer
{
int StartPlayback()
{
myHelper = new MmeHelper();
myHelper->myPlayer = this;
hPlayThread = CreateThread(NULL, 0, PlayThread, myHelper, 0, &PlayThreadId);
}
MmeHelper * myHelper;
};
static DWORD WINAPI PlayThread(LPVOID pThreadParam)
{
// Get a pointer to the object that started the thread
MmeHelper* helper = pThreadParam;
}