Как скрыть служебные функции от пользователя при компиляции библиотеки в си?
Я хочу скомпилировать библиотеку, но скрыть некоторые служебные функции. Я не могу просто засунуть их в .c файлы, потому что эти функции используются в разных модулях библиотеки, но я не хочу чтоб они были видны пользователю. Как это грамотно сделать?
Вот простой, но очень надуманный пример. Есть библиотека из 3 хедеров и 3 исполняемых файлов. В каждом файл реализована одна функция. Одна из этих функций использует в своей реализации две другие, я хочу чтоб видно было только ее.
multiplier.h
int multiplication(int a, int b);
multiplier.c
#include "multiplier.h"
int multiplication(int a, int b) {
return a * b;
}
summator.h
int sum(int a, int b);
summator.c
#include "summator.h"
int sum(int a, int b){
return a + b;
}
mult_summ.h
#include "multiplier.h"
#include "summator.h"
int mult_sum(int a, int b);
mult_summ.c
#include "mult_summ.h"
int mult_sum(int a, int b) {
return sum(multiplication(a, b), sum(a, b));
}
Я хочу, чтоб пользователь видел только функцию в файле mult_sum.h, как мне это сделать?? Вот мой cmake файл
cmake_minimum_required(VERSION 3.17)
project(untitled2 C)
set(CMAKE_C_STANDARD 11)
include_directories(inc)
add_library(math STATIC src/summator.c src/multiplication.c src/mult_summ.c)
Ответы (1 шт):
Статическая библиотека — это просто архив с объектными файлами, так что полностью спрятать функции, которые используются в других модулях компиляции принципиально не получится.
Из нормальных решений — отдать пользователю только один хедр — mult_summ.h. И написать в нём что-то вроде «если кто-то будет использовать функции из библиотеки, не описанные в данном файле, то мы не ручаемся за последствия, а также можем уволить и/или засудить виновника».
Кроме того хорошей практикой будет дать какие-либо специфические имена внутренним функциям, дабы не возник конфликт с пользовательскими функциями, например начать имя с подчёркивания (_), имени библиотеки и/или добавить какой-нить суффикс, например _internal_.
Среди менее рациональных вариантом я бы выделил:
- слить все
*.cфайлы в один и объявить функции которые не должны экспортироваться, как статические. - заставить компилятор встраивать все функции, которые не должны быть экспортированы
Для динамических библиотек можно объявить некоторые символы скрытыми. Для PE-EXE (dll) все символы по умолчанию являются скрытыми, а для ELF это делается как-то так. В cmake это будет выглядеть как:
add_library(math SHARED src/summator.c src/multiplication.c src/mult_summ.c)
set_target_properties(math PROPERTIES C_VISIBILITY_PRESET hidden)