Недопустимое исключение приведения Xml.Serializer в элементе управления C ++ ActiveX, размещенном в приложении C # .Net 4.0.

У меня есть приложение C # .Net 4.0, в котором размещается элемент управления C ++ ActiveX, использующий C ++ DLL с включенным CLR. DLL имеет основную функцию загрузки параметров для OCX и использует для этого XML.Serializer.

Этот стек работает нормально, когда все компоненты встроены в MS Visual Studio .Net 2003 и приложение C # работает в .Net 1.1.

Однако, когда все модули мигрируют в VS2010 и Приложение в .Net 4.0, я получаю страшное исключение приведения Xml.Serializer из-за несоответствующего контекста.

Исключение происходит в 4-й строке:

FileStream* fs = __gcnew FileStream( filename, FileMode::Open );
XmlReader* reader = __gcnew XmlTextReader( fs );
XmlSerializer* serializer = __gcnew XmlSerializer( __typeof(MyClass) );
MyClass* obj = __try_cast<MyClass*>(serializer->Deserialize(reader));

Вот заявление об исключении:

[A]MyClass cannot be cast to [B]MyClass.
Type A originates from 'ParameterModule, Version=0.0.0.0, Culture=neutral,      PublicKeyToken=null' in the context 'Default'
at location 'C:\path\to\module\ParameterModule.dll'.
Type B originates from 'ParameterModule, Version=0.0.0.0, Culture=neutral,  PublicKeyToken=null' in the context 'LoadNeither'
at location 'C:\path\to\modu~\ParameterModule.dll'.

в ParameterModule.ParaClass.execute_DeSerialize ()
Исключение было брошено.

Обратите внимание, что контекст «LoadNeither» имеет путь к тильда (~) персонаж. Контекст по умолчанию имеет полный путь.

DLL взаимодействия для элемента управления ActiveX автоматически генерируется VS2010.

Интересно, что вызывает исключение.
Это несоответствие в пути? Я не уверен, но я думаю, что DLL была загружена только один раз.

Или это несоответствие по контексту?
Если это происходит из-за несоответствия контекста, как мы можем убедиться, что контекст загрузки для модулей Interop, таких как элементы управления C ++ ActiveX?
Или мы можем указать Xml.Serializer для загрузки DLL, содержащей классы сериализации в контексте по умолчанию?

Я искал везде, и я не мог найти решение. Чем больше я прочесываю интернет, тем больше это становится для меня загадкой. Заранее спасибо.

0

Решение

но я думаю, что DLL была загружена только один раз

Нет, он загрузился дважды. И это проблема, идентичность типа .NET — это не просто пространство имен + имя типа, оно также включает сборку, из которой он был загружен. Это контрмера DLL Ад, она гарантирует, что вы не можете иметь один и тот же тип, загруженный более одного раза из разных DLL с конфликтующим определением.

Контекст «LoadNeither» является подсказкой к вашей проблеме. Вы каким-то образом загружаете эту сборку необычным способом. Обычный способ сделать это — использовать Assembly.LoadFile (), очень опасный метод, который следует использовать только в очень особых случаях, когда вы намеренно не хочу, чтобы типы соответствовали Вы должны всегда использовать LoadFrom (), но по-настоящему отдавать предпочтение Load (), когда можете. И вы обычно можете, поместив DLL в нужную директорию или используя <probing> элемент в файле app.exe.config.

Получение версии 0.0.0.0 также не очень полезно, кстати, [AssemblyVersion] очень важна для .NET.

1

Другие решения

Это странно, но исключение не произошло, когда мы использовали static_cast

MyClass* obj = static_cast<MyClass*>(serializer->Deserialize(reader));

Хотя этот ответ не решает проблему загрузки модуля дважды, этот обходной путь может помочь кому-то там.

0

По вопросам рекламы [email protected]