#c #mysql #user-defined-functions
#c #mysql #определяемые пользователем функции
Вопрос:
У меня есть следующие два файла:
- foo.h
- bar.cpp
В foo.h
я удаляю переменную extern
.
Теперь я хотел бы использовать ту же переменную в bar.cpp
(после включения foo.h
).
В VS2008 и VS2010 я получаю unresolved external symbol
ошибки, в то время как в Ubuntu с gcc компиляция проходит успешно.
(А именно, я пытаюсь скомпилировать следующий исходный код:http://www.fromdual.com/using-mysql-user-defined-functions-udf ; foo.h ссылается на srv0srv.h и bar.cpp ссылается на исходный код. Все включения на месте, компиляция прошла успешно, связывание падает)
В чем может быть проблема?
Ответ №1:
Ключевое слово extern указывает компилятору, что следующая за ним переменная уже объявлена где-то еще. На самом деле это не выделяет пространство для переменной. Если вы хотите создать глобальную переменную, которую вы можете использовать, включив файл заголовка (что, кстати, обычно является плохой идеей), вы можете сделать это следующим образом.
В foo.h:
extern int myVar;
в foo.cpp:
int myVar;
myVar теперь находится в foo.cpp , но оператор extern в foo.h разрешает использование кода в других файлах (таких как bar.cpp ) чтобы получить к нему доступ, включив foo.h .
Ответ №2:
Когда вы используете extern
для объявления переменной (глобальной переменной в других исходных объектах или файлах), вы фактически указываете компилятору искать определение переменной где-то еще. В этом случае вам необходимо предоставить другой исходный файл, который определяет int myVar
.
Ответ №3:
Ваша переменная должна иметь ссылку где-нибудь в одном из исходных файлов. С помощью extern
ключевого слова вы только сообщаете, что «существует переменная», но компоновщик должен знать ее местоположение. Во время компиляции исходного кода будут созданы ссылки для переменных и т.д. Компоновщик создаст ссылку в соответствии с этими ссылками. Если вы на самом деле не создаете ссылку на переменную, компоновщик не сможет найти ссылку, поэтому он выдаст ошибку. Если вы используете extern
, вы говорите, что не создавайте ссылку на эту переменную или любую другую вещь здесь. Но где-то еще должна быть ссылка на это.
Комментарии:
1. Спасибо! Чего я не понимаю, почему код компилируется, но не связывается в VS2010, и почему он работает с gcc под Linux?
Ответ №4:
Проблема заключалась в том, что упомянутый символ должен быть экспортирован (через dllspec) из библиотеки dll, чтобы быть видимым извне. Только ключевое слово extern не позволяло увидеть его извне.