Esent аварийно завершает работу с Windows 8 в проекте Delphi
Я использовал ESENT для своих проектов довольно широко, и мне очень нравится, как легко и быстро он работает. И стабильный тоже!!
Но у меня огромная проблема с Windows 8!!! Независимо от того, как я связываюсь с esent.dll (динамически или статически) всякий раз, когда я вызываю что-то, кроме JetSetSystemParameter, dll падает, забирая мое приложение с обрыва.
К сожалению, я до сих пор не могу запустить его. Мой код без проблем работал с Windows 7 или старше. Но в Windows 8 происходит сбой esent.dll при попытке создать экземпляр (недопустимая операция с плавающей запятой).
Я перепробовал все возможные соглашения о вызовах. Это определенно НЕ проблема. Я попробовал еще немного и обнаружил эту странную ситуацию: 1. Я создал демонстрационное приложение, используя VS 2012, и JetCreateInstance работал просто отлично. 2. Точно такой же код в Delphi XE3 отправит esent.dll сбой. 3. Я создал DLL, используя VS 2012, экспортируя метод, который отлично работал в вышеупомянутом демонстрационном приложении, думая, что это ошибка Delphi. 4. Затем я загрузил DLL в демонстрационный проект Delphi (пробовал с 6, XE2 и XE3). Называется метод и БУМ. Та же авария.
Теперь я предполагаю, что Microsoft не допустит?!? любая другая среда разработчика для правильной работы с esent.dll. Это возможно???
1 ответ
Ошибка, недопустимая операция с плавающей запятой, заставляет проблему звучать так, как будто она связана с управляющим словом с плавающей запятой.
По умолчанию Delphi разоблачает исключения с плавающей запятой. Поэтому, когда код просит модуль с плавающей запятой выполнить операции, которые приводят к ошибкам, сигналы FPU преобразуются в исключение.
Но большинство других сред разработки Windows маскируют эти исключения на FPU. Такой код написан в предположении, что среда выполнения имеет маскированные исключения FPU. Но если вы вызовете DLL из Delphi, среда выполнения будет иметь маскированные исключения FPU, что нарушит это предположение. Я подозреваю, что если вы замаскируете исключения FPU, то ваши проблемы исчезнут.
Чтобы проверить, является ли это проблемой, вы можете просто добавить это к своему коду, выполненному в начале его жизни:
Set8087CW($027F);
Это замаскирует все исключения и установит для управляющего слова FPU значение по умолчанию для Windows.
В более долгосрочной перспективе вы можете захотеть замаскировать исключения перед каждым вызовом этой DLL, а затем восстановить управляющее слово FPU, когда вызов DLL возвращается.
Это немного опасная игра, использующая библиотеки, поставляемые с Delphi, так как Set8087CW
не является потокобезопасным из-за использования глобальной переменной Default8087CW
, Если вы хотите прочитать больше об этой проблеме, я отсылаю вас к QC# 107411.