- 開啟-fvisibility=hidden妈嘹,編譯為靜態(tài)庫忿晕,不管函數(shù)導(dǎo)不導(dǎo)出,在nm中查看逻杖,顯示都為T。
例如:
頭文件common.h中的內(nèi)容如下:
#define FUNC_EXPORT __attribute__((visibility("default")))
void funa1(void);
FUNC_EXPORT void funa2(void);
FUNC_EXPORT void funb(void);
文件a.c中的內(nèi)容如下:
#include "common.h"
void funa1(void)
{
}
void funa2(void)
{
}
CMakeLists.txt中的內(nèi)容如下:
cmake_minimum_required(VERSION 3.15)
project(TestHidden C CXX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
add_library(suba STATIC a.c)
add_library(suba2 SHARED a.c)
編譯后贩耐,用nm查看libsuba.a中的函數(shù):
image.png
-
編譯為動(dòng)態(tài)庫弧腥,在nm中查看,導(dǎo)出函數(shù)顯示為T潮太,非導(dǎo)出函數(shù)顯示為t管搪。
查看libsuba2.so中的函數(shù):
image.png -
使用objdump -t查看靜態(tài)庫中的函數(shù),可以看出導(dǎo)出函數(shù)和非導(dǎo)出函數(shù)的區(qū)別铡买。
非導(dǎo)出函數(shù)有.hidden標(biāo)記更鲁。
image.png - 應(yīng)用程序可以直接調(diào)用靜態(tài)庫中的非導(dǎo)出函數(shù),而不會(huì)鏈接出錯(cuò)奇钞。
例如澡为,main.c中的內(nèi)容如下:
#include "common.h"
int main(void)
{
funa1();
return 0;
}
CMakeLists.txt中增加兩行:
add_executable(main main.c)
target_link_libraries(main suba)
編譯成功:
image.png
- 動(dòng)態(tài)庫直接調(diào)用靜態(tài)為中的非導(dǎo)出函數(shù),會(huì)報(bào)錯(cuò)景埃。
這種情況通常發(fā)生在:應(yīng)用程序調(diào)用動(dòng)態(tài)庫中的函數(shù)A媒至,A調(diào)用靜態(tài)庫中的非導(dǎo)出函數(shù)B。
例如:
文件b.c中的內(nèi)容如下:
#include "common.h"
void funb(void)
{
funa1();
}
文件main.c中的內(nèi)容如下:
#include "common.h"
int main(void)
{
funab();
return 0;
}
修改CMakeLists.txt如下:
add_library(subb SHARED b.c)
add_executable(main main.c)
target_link_libraries(main subb suba)
編譯失敼柔恪:
image.png
- 指定動(dòng)態(tài)庫依賴靜態(tài)庫拒啰,生成動(dòng)態(tài)庫時(shí)會(huì)把所需的符號(hào)定義拷貝到自身中,不會(huì)鏈接出錯(cuò)完慧。
修改CMakeLists.txt如下:
target_link_libraries(subb suba)
target_link_libraries(main subb)
編譯成功:
image.png
靜態(tài)庫中的函數(shù)拷貝到動(dòng)態(tài)庫中后谋旦,是外部的還是內(nèi)部的?
從前面的例子中可以看出屈尼,會(huì)保持函數(shù)原來的可見性册着。
例如,funa1在靜態(tài)庫中是內(nèi)部的(帶.hidden)脾歧,那么拷貝到libsubb.so后甲捏,是內(nèi)部的(nm顯示為t)。
funa2在靜態(tài)庫中是外部的(不帶.hidden)鞭执,那么拷貝到libsubb.so后摊鸡,是外部的(nm顯示為T)绽媒。