Search code examples
winapipointersc++-climanaged-c++

Cast native pointer to a C++\CLI managed object reference?


I have a callback that is called through a delegate. Inside it I will need to treat the buffer data that arrive from a record procedure. Normally in a unmanaged context I could do a reinterpret_cast on dwParam1 to get the object reference. But in a manged context how can I cast a DWORD_PTR to a managed object ref?

    static void WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) 
    {
        ControlLib::SoundDevice^ soudDevice = ?cast_native2managed?(dwParam1);

Solution

  • Here ya go, more or less what gcroot (per my comment above) does:

    using namespace System;
    using namespace System::Runtime::InteropServices;
    
    // track an object by a normal (not pinned) handle, encoded in a DWORD_PTR
    DWORD_PTR ParamFromObject(Object^ obj)
    {
        return reinterpret_cast<DWORD_PTR>(GCHandle::ToIntPtr(GCHandle::Alloc(obj)).ToPointer());
    }
    
    static void WaveInProc(PVOID hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) 
    {
        // unwrap the encoded handle...
        GCHandle h = GCHandle::FromIntPtr(IntPtr(reinterpret_cast<void*>(dwParam1)));
        try
        {
            // and cast your object back out
            SoundDevice^ x = safe_cast<SoundDevice^>(h.Target);
        }
        finally
        {
            // remember to free the handle when you're done, otherwise your object will never be collected
            GCHandle::Free(h);
        }
    }