System.Drawing.Image для Visual C ++ / MFC Picture Control - PullRequest
1 голос
/ 12 января 2012

Я пытаюсь получить System.Drawing.Image (сгенерированный в .NET dll) в элемент управления изображением в приложении Visual C ++ / MFC. Я новичок в COM / Interop, но у меня есть interop'ing работает. Однако я не уверен, как передать растровые данные из C # в C ++.

Основной процесс:
1. Вызовы C ++ / MFC на COM-сервере (взаимодействие)
2. C # COM-сервер вызывает .NET DLL
3. Создать System.Drawing.Image в .NET DLL
4. C # COM-сервер возвращает растровые данные в некоторой форме (взаимодействие)
5. C ++ / MFC отображает растровое изображение

На C # COM-сервере у меня есть:

Bitmap bm = new Bitmap(img);
IntPtr hbm = bm.GetHbitmap();
return hbm;

Где img - это System.Drawing.Image, который я хочу отправить. Метод возвращает IntPtr, который маршалируется до long*

В моем приложении MFC C ++ Test у меня есть:

long pOutHB;

pQRCodePtr->Generate(m_sQRText.AllocSysString(), 50, 50, &pOutHB);

HBITMAP hb = (HBITMAP) pOutHB;
m_QRCodePicture.SetBitmap(hb);
m_QRCodePicture.Invalidate();
m_QRCodePicture.UpdateData();

Но ничего не вставляется в элемент управления изображением. Я также попытался создать CBitmap с использованием HBITMAP, но это также не увенчалось успехом. Я проверил, что .NET dll / COM-сервер генерирует правильный образ.

В большинстве моих исследований по этой проблеме было обнаружено использование растрового изображения C ++ и создание System.Drawing.Image, а не в другом направлении (как этот вопрос: Безопасность передачи дескриптора HBITMAP из неуправляемого в управляемый код для созданного System.Drawing.Bitmap )

Я иду по правильному пути здесь? Я понимаю, что мой код может быть полностью неверным. Я ищу что-то, чтобы указать мне правильное направление здесь. Моя первая попытка состояла в том, чтобы передать массив byte[], но некоторые показания указали мне в направлении передачи указателя HBitmap как более эффективного.

1 Ответ

0 голосов
/ 12 января 2012

Для дальнейшего использования, оказывается, я все делал правильно. Дескриптор HBITMAP действителен и сохраняется даже после возврата из функции .NET и прохождения через COM-взаимодействие. Согласно MSDN, вам нужно очистить объект.

Добавление некоторой очистки, это работает. Generate - это вызов службы оболочки COM, который возвращает IntPtr, который маршалируется до long.

long pOutHB;

pQRCodePtr->Generate(m_sQRText.AllocSysString(), 200, 200, &pOutHB);

HBITMAP hb1 = (HBITMAP) pOutHB;

HBITMAP oldHB = m_QRCodePicture.SetBitmap(hb1);
if (oldHB)
{
    DeleteObject(oldHB);
}
...