C ++ DLL создает исключение во время выполнения - PullRequest
2 голосов
/ 15 декабря 2010

Мое приложение C # вызывает функцию в C ++ DLL во время выполнения и выдает исключение.Сгенерированный код ошибки - 262. К сожалению, в документации Microsoft этого кода немного не хватает.

Как ни странно, это исключение не выдается при запуске DLL из тестового приложения C ++, котороечасть того же решения Visual Studio, что и DLL (отдельный проект).(Приложение C # находится в совершенно отдельном решении.) Код ошибки возвращается при вызове CoInitializeEx, который инициализирует COM и является первым шагом, который мое приложение использует для запроса WMI.

Единственный единственныйДругая вещь, по-видимому, связана с тем, что когда я открываю DLL с помощью Dependency Walker, я получаю следующие ошибки и предупреждения:

Ошибка: по крайней мере одна необходимая неявная или перенаправленная зависимость не найдена.Предупреждение. По крайней мере один модуль зависимости задержки и загрузки не найден.Предупреждение: по крайней мере один модуль имеет неразрешенный импорт из-за отсутствующей функции экспорта в модуле, зависящем от задержки и загрузки.

Единственное, что мне приходит на ум, - это отсутствие «требуемой неявной или перенаправленной зависимости»."имеет то, что нужно, чтобы заставить CoInitializeEx работать.Согласно Dependency Walker, эти модули не могут быть найдены:

  • MSVCR90D.DLL
  • IESHIMS.DLL
  • WER.DLL

Любые мысли или предложения приветствуются.Спасибо.

Ответы [ 5 ]

4 голосов
/ 15 декабря 2010

Ваша обработка ошибок не кошерна, реальная ошибка, которую вы, вероятно, получаете, - 0x80010106, последнее слово - 262. Код ошибки - RPC_E_CHANGED_MODE, «Невозможно изменить режим потока после его установки».Именно это CoInitialize / Ex возвращает, когда он вызывался раньше, и вы пытаетесь перейти с STA на MTA или наоборот.

Это невозможно, состояние квартиры для потока заблокировано напервый вызов CoInitializeEx ().Вам нужно выяснить, где произошел первый звонок.Это могло бы быть сделано CLR для управляемого потока, например.Состояние квартиры для потока определяется с помощью метода [STAThread] или [MTAThread] в методе Main () для потока запуска.Или Thread.SetApartmentState () для управляемого потока, который вы создаете сами.Поток резьбы всегда является MTA, который не может быть изменен.

Изменение состояния квартиры для потока может иметь много побочных эффектов.

1 голос
/ 07 января 2011

В вашем конкретном сценарии, вероятно, лучше всего использовать отдельный поток.

Создание потоков из DLL - дело грязное, потому что DLL не владеет временем жизни процесса; владелец - EXE.

Однако ... если вы запустите его синхронно (создайте поток; инициализируйте; дождитесь завершения потока; затем продолжите), вы, как правило, будете в безопасности. Вы можете кэшировать поток, так что вам не нужно каждый раз создавать и CoInitialize () его, но не позволяйте ему работать в фоновом режиме и возвращаться к вызывающей стороне: опять же, возникают тонкие проблемы времени жизни.

1 голос
/ 15 декабря 2010

Я предполагаю, что у вас не установлена ​​Visual Studio 2008 C ++, как тогда, когда у вас будет MSVCR90D.dll. Эта dll является dll только для отладки, что означает, что вы пытаетесь загрузить DLL, скомпилированную как отладочную DLL.

Что касается остальных ... см. Эту ветку: Обозреватель зависимостей сообщает, что IESHIMS.DLL и WER.DLL отсутствуют?

0 голосов
/ 12 мая 2014

Ошибка WIN32 = 262: HRESULT = -2147024634 (0x80070106). Это что-то еще. CoInitializeEx должен вызываться для каждого потока только один раз, но если он вызывается более одного раза, для каждого CoInitializeEx должен быть один CoUninitialize.

0 голосов
/ 15 декабря 2010

Убедитесь, что вы скомпилировали все в режиме выпуска или отладки.

Используете ли вы какие-либо функции на основе http из IE?Мне любопытно, почему вы зависите от ieshims.dll.

...