У меня есть управляемая c ++ dll с несколькими управляемыми классами, которые, в свою очередь, вызывают собственный код c ++ в библиотеке, которую я статически связал с dll.Тем не менее, если я пытаюсь запустить RegAsm.exe на dll, инструмент правильно сообщает «нет типов, которые мы зарегистрировали», но тогда зависает .Я очень уверен, что это проблема loader lock , и моя dll зависает, когда RegAsm пытается загрузить его.Я использую Visual Studio 2008, экспресс-издание.
Что меня озадачивает, что все отлично работает при помещении нативного кода в dll, но не при статической привязке его из библиотеки.Я знаю, что этот пост похож на этот вопрос , но у меня нет DllMain в моей dll, нет риска того, что я буду запускать код MSIL из DllMain.Кроме того, следование советам установки / clr для отдельных файлов не помогло.
Компиляция dll с / NOENTRY устраняет проблему блокировки, но приводит к разрыву приложения с исключением Type initializer for <Module> threw exception
и, по-видимому, рекомендуется только с.NET 2003.
Я подозреваю, что инициализация статических членов может быть возможным виновником, но почему это будет скомпилировано в MSIL в моей статической библиотеке, мне не под силу.
Простоуточнить: хотя мне не нужно запускать RegAsm.exe на dll, я использую его для проверки проблемы блокировки загрузчика.На самом деле я использую dll в ассемблере ac #, который реализует несколько COM-видимых классов - поэтому мне нужно сделать COM-регистрацию для этого.В конце C # IDE вылетает при регистрации взаимодействия COM, сообщая об ошибке времени выполнения R6033 c ++: Попытка использовать код MSIL из этой сборки во время инициализации собственного кода.Это указывает на ошибку в вашем приложении.Скорее всего, это результат вызова MSIL-скомпилированной (/ clr) функции из собственного конструктора или из DllMain.
Решена проблема, но мало что неясно, и мне любопытно:
Я заметил, что две статические переменные были добавлены в заголовочный файл в статически связанной библиотеке в то время, когда вещи перестали работать, что выглядело так:
// The whole header is forced to compile as native
#pragma managed(push, off)
....
static const std::locale commaSeparator(std::locale::classic(),
new DecimalSeparator<char>(','));;
....
#pragma managed(pop)
Перемещение инициализации в файл .cpp (и изменение static
на extern
) исправляет блокировку загрузчика.Может ли кто-нибудь указать, почему инициализатор вообще скомпилируется в MSIL?
До исправления, если я только # включил заголовочный файл из управляемого dll, все работало нормально.Но если бы я включил заголовок И также связанный с библиотекой, вещи не работали.Поскольку библиотека также использует заголовок внутри, я в итоге получил два экземпляра статической переменной?В любом случае, почему жалоба на запуск кода MSIL?
Хотя сейчас все работает, любая информация будет приветствоваться.