2013-02-18 5 views
0

У меня есть небольшая проблема или непонимание со скрытыми символами в xcode 4.6. Я искал всюду в Интернете и не мог найти какие-либо сообщения, имеющие одну и ту же проблему.xcode 4.6 видимость символов

В настоящее время я создал рамочный проект с простым файлом заголовок, содержащими так:

class Test 
{ 
public: 

    Test(){} 
    Test(){} 
}; 

int a(int n) {return n;} 

__attribute__((visibility("hidden"))) int b(int n) {return n;} 

__attribute__((visibility("default"))) int c(int n) {return n;} 

class X 
{ 
public: 
    virtual ~X(); 
}; 

class __attribute__((visibility("hidden"))) Y 
{ 
public: 
    virtual ~Y(); 
}; 

class __attribute__((visibility("default"))) Z 
{ 
public: 
    virtual ~Z(); 
}; 

X::~X() { } 
Y::~Y() { } 
Z::~Z() { } 

В настройках проекта я убедился в том, что «символы скрыты по умолчанию» переключаются на YES, и поэтому только функции int c, а класс z будет экспортирован или видим другим проектам.

Я создаю фреймворк без ошибок или предупреждений, а затем копирую/добавляю его в приложение для какао для тестирования.

Я могу включить заголовочный файл, но я все еще могу получить доступ ко всем классам и функциям.

Я надеюсь, что кто-то может объяснить, почему или где я ошибаюсь или столкнулся с этой проблемой раньше?

С уважением

ответ

1

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

Я пытаюсь объяснить это вам более простым образцом. Предположим, у вас есть два файла MyLib.h и MyLib.c.

MyLib.h:

int add(int a, int b); 

MyLib.c:

int add(int a, int b) { return a + b }; 

Если теперь дать add в hidden видимости и собрать все к библиотеке (MyLib), библиотека не будет иметь ни одного символа для add (как скрыто). В результате, если вы включите MyLib.h в другой файл, сделайте вызов функции add и, наконец, свяжите этот файл с MyLib, вы получите ошибку компоновщика, так как компоновщик будет жаловаться, что он не может найти реализацию для add (it имеет только объявление из файла H).

Однако, если пакет функции в самом заголовке, так MyLib.h является:

int add(int a, int b) { return a + b }; 

и вы даете add в hidden видимости, библиотека будет также иметь ни одного символа для add, но когда ты включить заголовок в другой файл, этот заголовок создаст символ для add точно в файл, который его импортировал, и, следовательно, вы не получите ошибку компоновщика и сможете вызвать add.

Импорт файла H означает только копирование всего содержимого файла H в место, где была указана инструкция по импорту. Теперь подумайте об этом: если вы копируете все содержимое файла H в своем вопросе в начало файла, в который вы его включаете, конечно, все объявленные там символы видны и могут использоваться в текущем проекте. Почему бы им не увидеть или использовать?Они не в библиотеке, да, но они находятся в заголовке и, следовательно, скомпилируются, когда ваш другой проект скомпилирован.

Символы, которые должны быть невидимы вне вашего текущего проекта («скрытые» символы), никогда не должны появляться в каком-либо общедоступном заголовочном файле вашего фреймворка. Почему бы вам сообщить о существовании символов в файлах заголовков, которые нельзя использовать в любом случае? Фактически, в большинстве случаев не показывать символы в файле заголовка уже достаточно, чтобы люди не могли их использовать. Причина их не экспортирования заключается только в том, что если символ существует, его можно использовать, даже если он не отображается каким-либо заголовочным файлом (для этого вам просто нужно написать собственный заголовочный файл или объявить его как символ external непосредственно в вашем код). Таким образом, создание скрытых символов - это просто защита, чтобы убедиться, что она не может использоваться ни при каких обстоятельствах.

+0

Спасибо Мекки, конечно, я совершенно глуп (мозг пожарен, но без оправдания). Я думаю, что меня путала с [этой яблочной страницей] (https://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html), потому что в ней показывался пример, который я хотя был в файле заголовка или jsut демонстрирует, где разместить __attribute __ ((видимость («по умолчанию»))) или что-то еще. Итак, если бы была встроена функция int add, например, она была бы скрыта правильно? – themadme

+0

Если вы объявите функцию 'inline', но поместите ее в заголовок, то она будет отображаться везде, где заголовок включен. Если вы хотите сделать функцию невидимой вне вашей библиотеки, объявите ее как «скрытую» и убедитесь, что она не отображается в любом заголовочном файле вашего пакета фреймов. Просто используйте частный файл H, который доступен только для файлов вашей инфраструктуры, но не скопирован в пакет фреймворков и, следовательно, не отображается в проекте, который связан с вашей картой. – Mecki

+0

Еще раз спасибо за мудрость Мекки. Теперь я не могу дождаться возвращения домой и продолжить преобразование моего проекта Windows в Mac и, надеюсь, Linux. Еще раз спасибо. – themadme

Смежные вопросы