Получить удаленное растровое изображение, используя дескриптор HBITMAP в C # - PullRequest
0 голосов
/ 09 сентября 2010

У меня есть MarshalByRefObject, который мне нужно было сериализовать и сохранить (в базе данных), чтобы я мог десериализовать и сослаться на него позже. Я решил подходить к этому по-другому: сейчас я работаю с Windows Service, которая просто поддерживает MarshalByRefObjects «живой» (обратите внимание, что RemoteObject на самом деле является сторонним объектом, который я не создаю сам):

// This is the object which extends the MarshalByRefObject class
RemoteObject myRemoteObject = new RemoteObject;

TcpServerChannel channel = new TcpServerChannel(6789);
ChannelServices.RegisterChannel(channel, true);

ObjRef objRef = RemotingServices.Marshal((System.MarshalByRefObject)myRemoteObject, id);

В другом домене приложений я просто подключаю и получаю объект; все отлично работает:

RemoteObject myLocalObject = (FCEngine.IFCVerificationSession)Activator.GetObject(
                           typeof(FCEngine.IFCVerificationSession),"tcp://localhost:6789/" + id);

Теперь проблема в том, что RemoteObject содержит свойство, которое является просто дескриптором HBITMAP, приведенным к типу long. Я могу легко достать ручку. Обычно (локально) я бы сделал:

IntPtr hbitmap = (IntPtr)myLocalObject.ContextImage;
System.Drawing.Bitmap bmp = System.Drawing.Image.FromHbitmap(hbitmap);

Это не работает в текущем случае. Я получаю System.Runtime.InteropServices.ExternalException Я предполагаю, что проблема в том, что hbitmap является дескриптором некоторой памяти, которая не существует в локальном домене приложений, но в домене приложений Windows Service. У меня вопрос, какие у меня варианты:

  • RemoteObject довольно сложен, он похож на дерево, в котором вы пересекаете узлы, вызывая его функции. Третья сторона навязывает, что я могу пройти объект только один раз. Поэтому обход через службу, сохранение растровых изображений в базе данных и повторный удаленный просмотр не будут работать.
  • Идеально было бы иметь возможность вызывать функцию в службе Windows и передавать дескриптор hbitmap в качестве аргумента, возвращая фактическое растровое изображение. Это невозможно в службах Windows.
  • Я мог бы сохранить дескриптор в базе данных и сделать так, чтобы служба Windows опрашивала его. Затем он может получить растровое изображение и сохранить его в той же БД для меня. Затем я мог бы снова получить этот растр удаленно. Это очень уродливо, так как мне нужно растровое изображение немедленно.

По сути, я хотел бы знать, есть ли у вас предложения не выполнять некрасивые хаки, как в третьем варианте ... Какие у меня варианты?

решаемые Прямо сейчас я решил проблему, создав собственный объект, который расширяет MarshalByRefObject на стороне службы. Этот объект имеет метод для извлечения и сохранения растрового изображения путем передачи дескриптора. Я просто подхожу к объекту удаленно, точно так же, как к своему стороннему объекту. Слишком простое решение, хотя коллеге пришлось указать на это.

1 Ответ

1 голос
/ 09 сентября 2010

HBitmap - дескриптор, нет смысла сериализовать неуправляемые дескрипторы. Вам необходимо сериализовать растровое содержимое, воссоздать его (растровое изображение) на удаленной стороне, а затем переназначить вновь созданное hbitmap.

P.S. Физически дескриптор - это указатель на указатель, его значение применимо только при создании адресного пространства.

ИМХО.

...