Я пытаюсь понять видимость C++ в отношении библиотеки только заголовков и хочу убедиться, что у меня правильное понимание этого вопроса. В настоящее время я использую компилятор Clang 15.0.6.
Итак, насколько я понимаю/читаю, есть ли у меня методы в общей библиотеке A.so, как показано ниже
#define ATTRIBUTE_HIDDEN __attribute__((__visibility__("hidden")))
ATTRIBUTE_HIDDEN int foo (){
return 5;
}
int bar(){
return 6;
}
Тогда, если мы создадим A.so с флагом -fvisibility=hidden
, это заставит скрыть видимость всех символов, отмеченных макросом ATTRIBUTE_HIDDEN
, что предотвратит их видимость за пределами библиотеки. Поэтому, если B.so теперь связывается с A.so, то код внутри B.so может вызывать только метод bar(), а не метод foo(). Это правильно?
Более того, что, если теперь у нас есть библиотека C только для заголовков и пусть говорит, что она содержит util.h, который имеет следующие методы
#define ATTRIBUTE_HIDDEN __attribute__((__visibility__("hidden")))
inline ATTRIBUTE_HIDDEN int xxx (){
return 5;
}
inline int yyy(){
return 6;
}
Мне кажется, что если теперь какая-то другая общая библиотека D.so свяжется с ней, то D.so сможет вызывать методы xxx() и yyy() из библиотеки C только для заголовка, но если мы создадим D.so с флагом add_library(C INTERFACE .)
чем если другая общая библиотека E.so ссылается на D.so, чем внутри E.so, мы можем вызывать только yyy(), а не xxx(), поскольку более поздняя функция помечена скрытой. правильно ли я понимаю или я что-то упускаю.
Скрытая видимость и C++ не очень хорошо работают вместе. (Я знаю из личного опыта.) Чтобы получить дружественную к C++ «скрытую видимость» перед модулями C++20, используйте анонимное пространство имен. Для библиотеки только заголовков используйте комбинацию встроенного и анонимного пространства имен.
Ваше базовое понимание видимости файлов .so верное. Вот почему я немного удивлен вашим замешательством. Библиотеки только для заголовков по определению не имеют файлов .so, поэтому видимость вообще не имеет значения. Библиотеки только заголовков используются компилятором. Любой файл .cpp, включая библиотеку только заголовков, может вызывать эти библиотечные функции.
Большое спасибо за подтверждение, поэтому для библиотеки, которая использует только заголовки, видимость библиотеки не имеет никакого значения. Не могли бы вы также подтвердить мой другой запрос, то есть, если D.so связывается с библиотекой только заголовков, а E.so связывается с D.so, то в E.so мы можем вызывать только yyy().
@bourne: D.so не может связываться с библиотеками только для заголовков. Библиотеки только для заголовков не связаны, они скомпилированы. Вот почему я сказал «используется компилятором» и специально назвал файл .cpp. Если E.so захочет вызвать yyy
, ему также потребуется включить библиотеку C.
большое спасибо за разъяснение, возможно, это и было путаницей, потому что, если вы используете cmake, вы обычно делаете что-то вроде следующего: add_library(header_only_lib INTERFACE)
, а затем target_link_libraries(your_app_or_another_lib PRIVATE header_only_lib)
и target_link_libraries
, у меня сложилось неправильное впечатление. Еще раз спасибо.
Это было отмечено тегом C++14/17, но эти стандарты не имеют к этому никакого отношения. Самое близкое в Стандарте — это модули C++20.