Блокировка загрузчика (ошибка regsvr32 R6033) с управляемой DLL C++

У меня есть C++ dll, который реализует несколько COM-интерфейсов, которые я пытаюсь перенести на управляемый C++. Я установил флаг компилятора /clr и изменил свойство Runtime Library с /MT на /MD, чтобы избежать конфликта между этими двумя флагами, но это все, что я изменил. Когда он пытается зарегистрировать DLL во время процесса сборки, я получаю следующую ошибку:

R6033 - Попытка использовать код MSIL из этой сборки во время инициализации собственного кода. Это указывает на ошибку в вашем приложении. Скорее всего, это результат вызова MSIL-скомпилированной (/clr) функции из собственного конструктора или из DllMain.

Я прочитал о Loader Lock и не могу понять - я не добавил ни одного вызова в какой-либо управляемый код. Вот весь текст процедуры DllMain:

[Изменить - согласно комментарию ниже, я добавил неуправляемую #pragma в начало файла cpp без каких-либо улучшений. Модуль init - это весь код, содержащийся в библиотеках ATL, что я могу сказать.]

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    lpReserved;
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance, &MYGUID);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

2 ответа

Решение

Вы должны добавить флаг компилятора /clr только к файлам, которые используют управляемый код, а не для всего проекта.

Вот что делает "Мастер" Visual Studio, вот как я тестировал:

  • Создайте проект Visual C++ ATL
  • Добавлен простой объект ATL, чтобы иметь интерфейс COM (Project->Add Class)
  • Добавлен класс компонентов CLR. Мастер напомнил мне: "Вы добавляете компонент CLR в собственный проект. Ваш проект будет преобразован для поддержки Common Language Runtime".
  • Скомпилируйте проект, скомпилируйте нормально и зарегистрируйте нормально.
  • Проверил настройки проекта -> "Нет поддержки Common Language Runtime"
  • Проверил настройки clrcomponennt.cpp -> "Поддержка поддержки общего языка (/clr)"
  • Открыл dll в OleView -> COM интерфейс присутствовал
  • Открыл dll в.NET Reflector Red Gate -> присутствовал clrcomponent

Использование флага /clr сделало ваши методы управляемыми (т. Е. Они компилируются в MSIL), но вы вызываете их для DllMain, который не управляется. К сожалению, это примерно настолько, насколько мои ограниченные знания могут это сделать.

Другие вопросы по тегам