0

I currently have an array of System::Drawing::Bitmaps in a dll in managed C++ code. I would like to be able to call into the method in the managed C++ from unmanaged(native) C++. The question is how to do I pass the array back to unmanaged C++?

I can call GetHbitmap() on the managed C++ bitmap which returns an IntPtr. Should I pass an array of IntPtrs? Not quite sure the best way to do this. So to be clear I have this:

Managed C++ Method:

void GetBitmaps(<????>* bitmaps)
{
    //Calling into C# to get the bitmaps

    array<System::Drawing::Bitmap^>^ bmp=ct->DataGetBitmaps(gcnew String(SessionID));
    for(int i=0;i<bmp.Length;i++)
    {
        System::Drawing::Bitmap^ bm=(System::Drawing::Bitmap^)bmp.GetValue(i);
        IntPtr hBmp=bm->GetHbitmap();
    }

    //So now how to I convert the hBmp to an array value that I can then pass back to unmanaged C++(hence the <????> question for the type)
}

Is an array of HBITMAPS? And if so how can you convert the IntPtr hBmp to that array?

The managed C++ code works all well and good and correctly gets the array of bitmaps. but now I need to get those bitmaps back to the unmanaged C++ when the unmanaged C++ calls into the GetBitmaps method. I don't know what type of variable I should be passing in and then once I pass it in, what do I do to convert it to a type that unmanaged C++ can use?

1 Answers1

1

You'll surely need to create an unmanaged array to call your native code. You will also have to take care of proper cleanup afterwards. So basic code ought to look like this:

#include "stdafx.h"
#include <windows.h>
#pragma comment(lib, "gdi32.lib")
#pragma managed(push, off)
#include <yourunmanagedcode.h>
#pragma managed(pop)

using namespace System;
using namespace System::Drawing;
using namespace YourManagedCode;

    void SetBitmaps(const wchar_t* SessionID, CSharpSomething^ ct)
    {
        array<Bitmap^>^ bitmaps = ct->DataGetBitmaps(gcnew String(SessionID));
        HBITMAP* array = new HBITMAP[bitmaps->Length];
        try {
            for (int i = 0; i < bitmaps->Length; i++) {
                array[i] = (HBITMAP)bitmaps[i]->GetHbitmap().ToPointer();
            }
            // Call native method
            NativeDoSomething(array, bitmaps->Length);
        }
        finally {
            // Clean up the array after the call
            for (int i = 0; i < bitmaps->Length; i++) DeleteObject(array[i]);
            delete[] array;
        }
    }

There was not nearly enough information in your question to make this accurate, I had to use place-holder names for things like the C# class name and namespace and the native code .h file and function name and signature. You'll of course have to substitute them.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • This code has been very helpful as far as converting the managed bitmaps to HBITMAPs in the managed C++. Further question: I am actually calling this method from external unmanaged C++ code. So when I pass in the HBITMAP array from unmanaged C++ I pass it in as "HBITMAP* bitmaps". – user1059993 Feb 25 '13 at 02:22
  • Then in the managed C++ I allocate bitmaps=new HBITMAP[# of managed bitmaps]. Then I assign each element as indicated above. This all works fine and well except when I am coming back out of the managed c++ method: the array of bitmaps suddenly becomes NULL coming back out to the unmanaged code. I assume that perhaps I have to allocate the HBITMAP array differently in the managed C++? – user1059993 Feb 25 '13 at 02:25