Ограничение области действия глобальных символов из связанных объектов

У меня есть библиотека C в файле архива, clib.a. Я написал для него оболочку C++, cpp.o, и хотел бы использовать ее как статическую библиотеку:

ar cTrvs cppwrap.a clib.a cpp.o

Код, который ссылается на это, не сможет использовать материал из clib.a напрямую, если не включен правильный заголовок. Однако, если кто-то случайно создаст подходящий прототип, например. void myCoincidentallyNamedGlobalFunction() -- Меня интересует, какое определение myCoincidentallyNamedGlobalFunction будет применяться.

Поскольку к символам из clib.a нужно обращаться только в cpp.o, а не к чему-либо, связанному с cppwrap.a, есть ли способ полностью скрыть их, чтобы не было возможной коллизии (так что даже включение заголовка clib не удастся)?


person CodeClown42    schedule 15.05.2014    source источник
comment
clib.o вы создаете сами или представляете собой монолитный двоичный файл, который вам вручил кто-то другой и который вы хотите обернуть?   -  person Jeff    schedule 15.05.2014
comment
@ Джефф, я его строю, да.   -  person CodeClown42    schedule 15.05.2014
comment
Так что у вас есть пара вариантов, я думаю. Вы можете скрыть методы/переменные, которые вы не хотите экспортировать, в анонимных пространствах имен, что, вероятно, является самым чистым способом, или вы можете вручную strip -N или objcopy -N символов, которые вы не хотите отображать, из вашей окончательной распределенной библиотеки.   -  person Jeff    schedule 15.05.2014
comment
Хорошо, это может быть глупо, но может ли он поместить clib.o в собственную библиотеку, очистить имена и затем заархивировать их в cppwrap.a?   -  person Jiminion    schedule 15.05.2014
comment
Хорошо, может быть, не совсем глупо, поскольку Джефф думает то же самое. Хотя удаление символов в основном применялось для отладки....   -  person Jiminion    schedule 15.05.2014
comment
@Jeff Если да, то я этого не вижу (несколько вопросов). Это можно сформулировать так: Как я могу связать cpp.o с clib.o в cppwrap.a, не экспортируя символы из clib.o через cppwrap.a? clib.o на самом деле является архивом (clib.a), если это имеет значение (я редактировал вопрос в связи с этим)   -  person CodeClown42    schedule 15.05.2014
comment
@Джефф, ты прав, это здесь не применимо. Удаление.   -  person Andy    schedule 15.05.2014


Ответы (1)


Вы можете вручную удалить ненужные символы в окончательной объединенной библиотеке:

$ objcopy -N foo cppwrap.a (убрать символ)

Или, если вам нужны символы, но вы хотите убедиться, что внешние пользователи не могут получить к ним доступ:

$ objcopy -L bar cppwrap.a (символ локализации)

Или, если символ в clib.a должен быть видимым чем-то в cpp.o, но вы не хотите, чтобы он использовался кем-либо еще:

$ objcopy -W baz cppwrap.a (символ ослабления)

В этом случае коллизии с символами из других объектных файлов/библиотек будут зависеть от их использования, даже если символ все еще будет виден. Чтобы еще больше скрыть вещи или уменьшить вероятность даже почтительного столкновения, вы также можете использовать:

$ objcopy --redefine-sym old=new cppwrap.a

В некоторых случаях может помочь анонимное пространство имен, но не в том случае, если есть функциональность, которая нужна вашей оболочке, но она пытается скрыться от внешних пользователей.

person Jeff    schedule 15.05.2014
comment
Решение namespace, конечно же, не позволит функциям из cpp.o вызывать функции из clib.o. - person Some programmer dude; 15.05.2014
comment
objcopy возвращает не удаляющий символ 'baz', потому что он назван в перемещении. Если я неправильно понимаю ваш пример, использование пространства имен бесполезно, поскольку A) код, скомпилированный в clib.o, является кодом C, B) я вообще не хочу изменять clib, я просто хочу полностью заблокировать его внутри архива. - person CodeClown42; 15.05.2014
comment
Верно, сначала мне было непонятно, нужно ли ей просто скрывать лишние символы или она пытается обеспечить доступ к основным функциям только через имена символов cpp.o. - person Jeff; 15.05.2014
comment
@goldilocks Хорошо, кажется, я вижу, где ты сейчас немного лучше. Попробуйте objcopy -L baz cppwrap.a локализовать символ. - person Jeff; 15.05.2014
comment
Хммм. objcopy -L baz звучит правильно для меня, но затем говорит, whereX/whereX/clib.o: No such file or directory хотя ar -t cppwrap.a списки clib.o и whereX/clib.o созданы -- может быть, это отдельная дилемма, связанная с ar -T ? :\ - person CodeClown42; 15.05.2014
comment
Хорошо, в качестве хака вы можете попробовать objcopy -W baz clib.a, прежде чем ar вместе. Это сохраняет символ глобальным, но помечает его как слабый, так что конфликтующие символы в более поздних ссылках переопределяют его по умолчанию. - person Jeff; 15.05.2014
comment
У меня работает - вы должны упомянуть об этом в ответе (до сих пор я не знал о objcopy, это кажется правильным подходом в контексте). Спасибо. - person CodeClown42; 15.05.2014
comment
Рад, что мое решение работает для вас, но я не уверен, что оно действительно самое чистое из возможных. Если вы создаете как clib.a, так и оболочки, вы можете попытаться построить отдельные компоненты .o с соответствующими символами-оболочками C++, чтобы вы могли действительно удалить символы C, а не скрывать или ослаблять их. - person Jeff; 15.05.2014