Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.06.2014, 14:15   #1
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию Сериализация (сборка для COM-взаимодействия).

Доброе время суток всем!

Есть следующий код C#. В одном намспейсе находится класс Message, экземпляр которого я пытаюсь сериализовать. В нём есть поле перечисление и текстовое поле, матод уровня экземпляра PackMessage, упаковывающий объект в массив байт и статический метод UnpackMessage, занимающийся, соответственно, распаковкой.

И класс Class1, нужный для запуска сего процесса. В нём метод Foo, который упаковывает и тут же распаковывает объект Message. При распаковке возникает исключение (текст ниже).

Код:
namespace MySLib
{
    [Serializable]
    class Message
    {

        public MessageType mType;
        public string mText;

        public Message()
        {
            mType = MessageType.Type1;
            mText = "My message";
        }

        public Message(MessageType type, string text)
        {
            mType = type;
            mText = text;
        }

        public enum MessageType
        {
            Type1,
            Type2,
            Type3
        }
           
        public byte[] PackMessage()
        {
            MemoryStream stream = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(stream, this);
            byte[] pack = stream.ToArray();
            return pack;
        }

        public static Message UnpackMessage(byte[] pack)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream stream = new MemoryStream(pack);
            Message msg = (Message)bf.Deserialize(stream); //проблема здесь
            return msg;
        }
    }

 public class Class1
    {
        public void Foo()
        {
            Console.WriteLine("Ok! Foo started!");
            try
            {
                Message myMsg = new Message(Message.MessageType.Type2, "Some text");
                byte[] pack = myMsg.PackMessage();

                Message unpackedMsg = Message.UnpackMessage(pack);
                MessageBox.Show(unpackedMsg.mText);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                System.IO.File.WriteAllText(@"d:\trace_foo.txt", e.ToString());
            }
        }
    }
}
Всё это вызывается из CAVO. Код, на всякий случай привожу, но там, я уверен, всё правильно.

Код:
FUNCTION Start()
	LOcal myObj as Object

	myObj := OLEAutoObject{"MySLib.Class1"}
	myObj:Foo()     	
	
	WAIT
	
RETURN NIL
Проблема возникает при попытке десериализации объекта Message. Вот, что возвращает e.ToString().
Код:
System.Runtime.Serialization.SerializationException: Не удалось найти сборку "MySLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null".
   в System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
   в System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
   в System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
   в System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
   в System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
   в System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
   в System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   в System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   в System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   в MySLib.Message.UnpackMessage(Byte[] pack) в c:\Users\sVasilich\Documents\Visual Studio 2013\Projects\MySLib\MySLib\Class1.cs:строка 51
   в MySLib.Class1.Foo() в c:\Users\sVasilich\Documents\Visual Studio 2013\Projects\MySLib\MySLib\Class1.cs:строка 66
Подскажите, пожалуйста, что делаю не так? Хотя бы в какую сторону смотреть?
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...
sVasilich вне форума Ответить с цитированием
Старый 30.06.2014, 14:16   #2
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию

Если же подключить MySLib к проекту, написанному на C# проблем не возникает (подключал как Net-сборку, а не как COM-объект):

Код:
using MySLib;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Class1 myClass = new Class1();
            myClass.Foo();
            Console.ReadLine();
        }
    }
}

Для сборки .Net включены следующие параметры:
Регистрация для COM-взаимодействия = true
Конечная платформа = x86
Сделать сборку видимой для COM = true


Чтобы убедиться, что с сериализацией у меня всё парвильно, добавил к классу Class1 метод Bar, в котором тоже самое происходит со строкой string.
В этом случае упаковка и распаковка проходят успешно.
Код:
public void Bar()
        {
            Console.WriteLine("Ok! Bar started!");
            try
            {
                string testString = "some string";
                BinaryFormatter bf = new BinaryFormatter();
                MemoryStream stream = new MemoryStream();

                bf.Serialize(stream, testString);
                byte[] pack = stream.ToArray();

                stream = new MemoryStream(pack);
                string unpackedString = (string)bf.Deserialize(stream);
                MessageBox.Show(unpackedString);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                System.IO.File.WriteAllText(@"d:\trace_bar.txt", e.ToString());
            }

        }
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...
sVasilich вне форума Ответить с цитированием
Старый 01.07.2014, 11:21   #3
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию

Как ни странно, всё хорошо отработало через XmlSerializer. Исходный код сейчас не могу привести (добавлю вечером), но в общем всё аналогично.

Вопрос не снимается, хотелось бы работать без xml.

Версия класса Message c XmlSerializer.
Код:
    [Serializable]
    public class Message
    {

        public MessageType mType;
        public string mText;

        public Message()
        {
            mType = MessageType.Type1;
            mText = "My message";
        }

        public Message(MessageType type, string text)
        {
            mType = type;
            mText = text;
        }

        public enum MessageType
        {
            Type1,
            Type2,
            Type3
        }

        public byte[] PackToXml()
        {
            MemoryStream stream = new MemoryStream();
            XmlSerializer xs = new XmlSerializer(typeof(Message));
            xs.Serialize(stream, this);
            byte[] pack = stream.ToArray();
            return pack;
        }

        public static Message UnpackFromXml(byte[] pack)
        {
            MemoryStream stream = new MemoryStream(pack);
            XmlSerializer xs = new XmlSerializer(typeof(Message));
            Message msg = (Message)xs.Deserialize(stream);
            return msg;
        }
    }
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...

Последний раз редактировалось sVasilich; 01.07.2014 в 23:13. Причина: Как и обещал, выкладываю код с XmlSerializer
sVasilich вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Семафоры для межпрограммного взаимодействия Voronar Linux (Ubuntu, Debian, Red Hat, CentOS, Mint) 0 06.06.2013 20:34
Сериализация ацикличного направленного графа для сохранения в БД и десереализация с последующим разложением на деревья Ivan_32 Свободное общение 6 13.03.2013 10:01
Сериализация объектов для отправки их по сети Levsha100 Работа с сетью в Delphi 2 03.03.2012 22:01
Сборка для смешанного режима Лотос C# (си шарп) 0 04.01.2012 20:39
Сборка библиотеки boost регулярных выражений для С + +. Anubys Общие вопросы C/C++ 10 25.10.2011 00:35