Dll, встроенная в Delphi 2010/2009, не совместима с Delphi 7 при возникновении исключения - PullRequest
2 голосов
/ 25 июня 2010

Я собрал dll в Delphi 2010, и он используется в моем приложении delphi 7.

Я знаю о Unicode AnsiString / string, и, согласно моим тестам, все работает нормально до того момента, пока моя библиотека Delphi 2010 не выдвигает никаких исключений.Есть ли какое-либо специальное / обработанное исключение, совместимое с миром юникод / ​​AnsiString?То есть, способен ли мой Delphi 2010 вызвать исключение, которое может быть соответствующим образом обработано в моем приложении delphi 7?

Спасибо за любую помощь.

Данило.

Ответы [ 3 ]

4 голосов
/ 26 июня 2010

Видя, что Мейсон и Джероен подсказали мне, вот что: (Джероен, не бросай свой, у тебя тоже есть действительные баллы).

Джероен заявляет, что ничто для конкретного языка не должно пересекать границу dll.До определенного момента я согласен.Это зависит от предполагаемого использования библиотеки DLL, особенно когда речь идет о таких специфических для языка особенностях, как строка.Если вы разрабатываете dll, которая будет использоваться исключительно с проектами Delphi, и особенно когда это только с вашими собственными проектами Delphi, нет никаких причин связываться с PChar и т. П., Только чтобы избежать пересечения границ.

Так что, хотя исключения являются специфическими для языка, для меня это не главная причина, по которой исключения не могут выходить из dll.Ни тот факт, что из-за их языковой специфики может быть невозможно обрабатывать их вне dll.

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

Так как же вы гарантируете, что dll не попирает всю сторону вызывающей стороны?Я предполагаю, что есть много дорог, которые ведут в Рим, но самое простое, на мой взгляд, то, что делает OLE:

  • Каждый экспортируемый метод должен возвращать код, который сообщает вызывающей стороне, что все в порядке,или если что-то пошло не так.

  • Уточните коды возврата.Не просто сообщайте о том, что что-то пошло не так, используйте код для всего, что мешает методу делать то, что было вызвано.Также есть такие коды, как DLL_OK, DLL_OUT_OF_MEMORY, DLL_FILE_NOT_FOUND, DLL_INVALID_XXX (для сообщения о неверных входных параметрах) и т. Д.

  • В приложении, вызывающем dll, кодируйте общую функцию DLL_Check для проверки кодов возвратаи вызовите соответствующие исключения, которые остальная часть вашего кода может обрабатывать так, как считает нужным.

  • Используйте для этого специальные классы исключений.Т.е. общий класс исключений EDllError и различные его потомки для конкретных ситуаций, с которыми вам нужно разобраться.Это очень помогает, кроме E ... сделать кодирование.

  • Поскольку возвращаемое значение метода используется для отчетов ok / error: используйте параметры out или var в методах, которые должны возвращать значимые значения.

  • Проверьте документацию msdn по перетаскиванию OLE, чтобы найти примеры конкретных кодов возврата и как использовать параметры var и out для обмена информацией с вызывающим абонентом.

Ссылки:

3 голосов
/ 26 июня 2010

В Delphi всегда «допускаются» исключения, распространяющиеся между вызывающей стороной и вызываемой стороной через обычные границы DLL. Однако этот «допуск» был только в том случае, если и вызывающий, и вызываемый абоненты имеют одинаковую версию Delphi. Тот факт, что он работал между версиями, объясняется тем, что для нескольких выпусков макет и объявление класса Exception не изменились. Когда Delphi 2009 был представлен, многие детали реализации низкого уровня изменились (особенно это касается внутренней реализации строк). Это является причиной очевидного «провала». Один комментарий, что исключения никогда не должны избегать DLL, очень кстати.

3 голосов
/ 26 июня 2010

Я ударю в ответ; если постит Марьян, я оставлю свой.
Редактировать : Марьян попросил меня оставить мой ответ; , пожалуйста, вознаградите ее ответ несколькими голосами "за" , если вам нравится мой (поскольку мой ответ был сильно вдохновлен ее первым комментарием).

Вся идея DLL заключается в том, что они не зависят от языка.
Исключения являются сильно зависимой от языка функцией (многие языки имеют их, но каждый реализует их по-своему, иногда - в данном случае Delphi - разные версии одних и тех же языков используют по-разному).

Таким образом, библиотеки DLL должны позволять независимым от языка функциям выходить за пределы библиотеки DLL.
Зависимые от языка функции не должны пересекать границы DLL.
Это включает в себя исключения.

Что означает, что вы должны искать альтернативу.
Для этого в Windows API используются коды ошибок GetLastError и FormatMessage .
Вы можете придумать что-то похожее в вашей DLL.
Имейте в виду, что строки Delphi также зависят от языка, поэтому вы должны реализовать что-то вроде FormatMessage на основе символьных массивов (или указателей на символьные массивы).

- Йерун

...