2012-03-10 6 views
0

Я хотел написать unicode версию std :: exception и std :: runtime_error.
Итак, я подумал, что лучше сделать, чтобы просто реализовать реализации из стандартной библиотеки C++ и изменить их для поддержки unicode.Visual C++ Standard Library keywords

Так что я задрал исключение и stdexcept заголовков в Visual C++, скопированный код, сделал свои изменения.

Дело в том, что я не мог получить ссылку, если не удалю _CRTIMP_PURE. Я также удалил префикс _EXCEPTION_INLINE __CLR_OR_THIS_CALL от всех функций-членов.

Это работает, но мне очень любопытно, что все это делало.
_EXCEPTION_INLINE он буквально определен прямо над ним как #define _EXCEPTION_INLINE, и мои навыки в поисковых системах не могут найти никакой документации о том, что они делают.

Итак, кто-нибудь знает, что они предназначены? И почему это не связано, пока я не удалю префикс _CRTIMP_PURE из класса?

+3

Когда вы говорите «unicode», я думаю, что вы на самом деле имеете в виду «UTF-16», потому что 'char *' и 'std :: string' отлично подходят для UTF-8, который также является юникодом и превосходит к UTF-16. –

+0

Вы как минимум переименовали 'std :: exception' и' std :: runtime_error' после того, как скопировали и изменили их? Наличие класса взломанной библиотеки, сосуществующего с предоставленным компилятором, похоже на рецепт катастрофы. –

+1

@BenjaminLindley: Unicode всегда кодировался как UTF-16 в Windows, поэтому я думаю, что * Unicode * и * UTF-16 * используются взаимозаменяемо на территории Microsoft. –

ответ

2

На самом деле это не что-то загадочное (но может быть немного больно отслеживать, где они определены, но только немного). Они определены в заголовках, которые являются частью библиотеки, и они принимают разные определения в зависимости от того, как компилятор настроен для текущего запуска. В частности, эти макросы, похоже, в основном касаются того, настроен ли текущий прогон для /clr:pure.

_CRTIMP_PURE определяется как __declspec(dllimport), если вы связываетесь с DLL-версией среды выполнения C (а не с /clr:pure) и не имеет ничего общего.

Если ваша библиотека не является DLL (или если она не обязательно будет DLL всякий раз, когда конфигурация DLL настроена), вы не должны ее использовать. Вы, вероятно, не должны использовать его в любом случае, потому что вам нужно будет определить его по-разному, если в вашей библиотеке есть , а не когда используется ваша библиотека (это то, что делает Microsoft при создании библиотек времени выполнения C).

__CLR_OR_THIS_CALL используется библиотеками Microsoft, чтобы объявить функцию с __clrcall, если вы строите с /clr:pure (с указанием этих функций будет вызываться только управляемый код - компилятор может выполнять некоторые оптимизации в этом случае кажется).

И наконец, _EXCEPTION_INLINE используется для создания функций члена class exceptioninline при строительстве с /clr:pure.

Таким образом, нижняя строка, не используйте __CLR_OR_THIS_CALL или _EXCEPTION_INLINE, если вы не планируете поддерживать /clr для вашей библиотеки, и вы, вероятно, не следует использовать _CRTIMP_PURE в вашей реализации, но, вероятно, следует использовать что-то подобное из ваших собственных решений и под вашим контролем.

1

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

Нет проблем с дублированием интерфейса из std::exception и друзьями, и вы можете посмотреть на реализацию Visual Studio для вдохновения. Но ваша реализация должна использовать только публично документированные функции языка/библиотеки.

Смежные вопросы