Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Блок, относящийся только к системам Майкрософт
Если функция объявлена без атрибута
dllimport
илиdllexport
, то она не считается частью интерфейса DLL. Поэтому определение функции должно находиться в том же самом модуле или в другом модуле той же программы. Для того чтобы включить функцию в интерфейс DLL, необходимо в другом модуле объявить определение функции, указав для нее атрибутdllexport
. В противном случае при сборке клиента возникнет ошибка компоновщика.Если в одном и том же модуле вашей программы содержатся объявления одной и той же функции с атрибутами
dllimport
иdllexport
, то атрибутdllexport
имеет приоритет надdllimport
. Однако компилятор создает предупреждение. Например:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport void func1( void ); DllExport void func1( void ); /* Warning; dllexport */ /* takes precedence. */
Вы не можете инициализировать указатель на статические данные с адресом объекта данных, объявленного с атрибутом
dllimport
. Например, следующий код вызывает ошибки:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport int i; . . . int *pi = &i; /* Error */ void func2() { static int *pi = &i; /* Error */ }
Если при инициализации указателя на статическую функцию вы присвоите ему адрес функции, объявленной с атрибутом
dllimport
, то указатель будет ссылаться не на адрес функции, а на адрес преобразователя импорта DLL (это заглушка, которая передает управление функции). Следующее присваивание не порождает сообщения об ошибке:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport void func1( void . . . static void ( *pf )( void ) = &func1; /* No Error */ void func2() { static void ( *pf )( void ) = &func1; /* No Error */ }
Поскольку программа с атрибутом
dllexport
в объявлении объекта должна содержать определение этого объекта, то указатель на глобальную или локальную статическую функцию можно инициализировать с адресом функции с атрибутомdllexport
. Аналогичным образом указатель на глобальные или локальные статические данные можно инициализировать с адресом объекта данных с атрибутомdllexport
. Например:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport void func1( void ); DllImport int i; DllExport void func1( void ); DllExport int i; . . . int *pi = &i; /* Okay */ static void ( *pf )( void ) = &func1; /* Okay */ void func2() { static int *pi = i; /* Okay */ static void ( *pf )( void ) = &func1; /* Okay */ }
Завершение блока, относящегося только к системам Майкрософт