У меня есть 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 на стороне службы. Этот объект имеет метод для извлечения и сохранения растрового изображения путем передачи дескриптора. Я просто подхожу к объекту удаленно, точно так же, как к своему стороннему объекту. Слишком простое решение, хотя коллеге пришлось указать на это.