Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Библиотеки  (Прочитано 8877 раз)
0 Пользователей и 7 Гостей смотрят эту тему.
seaman
Гость
« : 12-04-2010 13:45 » 

Делаю статическую библиотеку (библиотеку импорта - .lib). Похоже снаружи ее будут видны только методы, которые определены в cpp файлах или которые снабжены __declspec(dllexport) по аналогии с dll.
Вопрос 1: правильно ли я понял, или что-то не так - может для lib что-то свое есть? Где вообще можно почитать по lib (по dll много, по lib не нашел ничего Жаль )
Вопрос 2: Из dll естественно невозможно инлайнить методы. Из lib можно?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 12-04-2010 13:49 » 

Будет видно всё, на что есть заголовки. И если заголовков на какие-то типы нет (например, они были только в .cpp), но пользуясь телепатическими навыками, написать эти заголовки, то всё равно такие типы будут видны.

.lib - это лишь свалка объектных файлов. Поэтому в стороннее приложение будет линковаться всё, для чего найдётся корректное объявление.
Записан
seaman
Гость
« Ответ #2 : 12-04-2010 13:57 » 

Весьма странно... Беру dumpbin /SYMBOLS My.lib и не вижу ни одного символа, у которого нет __declspec(dllexport), или который определен в .h файле...

Как тогда это объяснить?

Не хочу включать в проект полностью файл .h, в котором определен какой-то метод, хочу включать спецнаписанный файл .h, в котором метод только писан, а не определен. А определения методов с кодом пусть валяются в предварительно скомпилированной библиотеке .lib.

Думаю так ускорить процесс компиляции - раз, если понадобится распространять .lib и спецфайл .h без реализации, а только с определением - два.
« Последнее редактирование: 12-04-2010 14:40 от Sel » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 12-04-2010 14:19 » 

seaman, а чем плохо разделение по *.H и *.CPP ?
Записан

seaman
Гость
« Ответ #4 : 12-04-2010 14:22 » 

форсИнлайн функции нормально компилируются только если они определены, а не просто объявлены в .h
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 12-04-2010 14:27 » 

Что касается инлайна, так компилятор и в обычном случае (по стандарту) не обязан метод, отмеченный как inline, делать инлайном.
Ещё меньше вероятности, что он поступит так с методом, вынесенным в .cpp и скомпилированным во внешнюю статическую библиотеку.

Если тебе нужна оптимизация по скорости с помощью inline-ов, и эти методы у тебя светятся в интерфейсе библиотеки - может, тебе нужно тогда спрятать класс с инлайнами за неким внешним интерфейсом, враппер какой-то сделать?
Записан
seaman
Гость
« Ответ #6 : 12-04-2010 14:35 » new

Я говорил про forceinline - по идее он должен заставить инлайнить.

Ну обертка выход, если хочешь скрыть реализацию. А вот неужели никто не пробовал ускорить компиляцию просто отдельно компилируя библиотеки и подключая их к конечному продукту. Тогда не нужно перекомпилировать весь проект, достаточно только библиотеку, в которую внес изменения.

Ну а все-таки кто-нибудь встречал описание работы с lib для новичков? Я просто хотя бы для себя хочу уяснить, разложить по полочкам как с ней работать...

ЗЫ: извините - убегаю. Если что отвечу завтра. Спасибо.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 18-04-2010 17:04 » 

seaman, lib - это просто множество obj-файлов, собранных в один файл. И всё. Из этого вытекают абсолютно все следствия по работе с lib.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
seaman
Гость
« Ответ #8 : 19-04-2010 04:40 » 

Да, я тут немного поисследовал. Это на первый взгляд lib - просто сборище obj, на самом деле не всегда. Вот результаты (больше вопросов, чем результатов).

По dll больше инфы - поэтому стал делать ее, тем более, что lib при этом автоматом получается.

1. Делаем WIN32 проект. Из МСДН:
The __thiscall calling convention is used on member functions and is the default calling convention used by C++ member functions that do not use variable arguments.

Т.е. по умолчанию для функций-членов класса используется __thiscall. Экспортирую (lib/dll - неважно) функцию-член - вижу на выходе __thiscall. Но не у всех функций, а только не у статических. В том числе и у операторов.

Использую их в основном проекте. Функции нормально используются, находятся - все ОК.
А вот с операторами проблема. Линкер ищет не
 
Код:
 bool __thiscall UTILS::operator!=()
а
Код:
  bool __cdecl UTILS::operator!=()
Такой, конечно, не находит и выдает ошибку.

Кажется понял, почему так - потому что хочет использовать первый оператор != из следующего вопроса - friend оператор, а он не член - поэтому и ищет __cdecl.
Использую так:
Код:
    UTILS::String dtr = _T("Проба!");
    UTILS::String ppp = _T("Проба1");
    if(dtr != ppp)

Следовательно вопросы:
>>В каком случае выбирается какой оператор.
>>Как заставить использовать второй?


2. Почему-то не все операторы экспортируются.
Как экспортирую?:
Код:
class __declspec(dllexport) String
{
...
TH_FINLINE friend bool operator==(const String& a, const String& b) {...}
TH_FINLINE friend bool operator==(const String& a, const wchar_t* cStr) {...}
TH_FINLINE friend bool operator==(const wchar_t* cStr, const String& a) {...}
TH_FINLINE friend bool operator!=(const String& a, const String& b) {...}
TH_FINLINE bool operator!=(const String& a) {...}
...
}

Последний экспортируется всегда, а все friend нет. Вынес определение в cpp файл, убрал TH_FINLINE - не помогло. __declspec(dllexport) в cpp файл не вынести - ругается на повторный линк

>>Как экспортировать friend операторы (функции) в .dll?

Дополнение: здесь можно попробовать использовать def файл. Вечером попробую...

3.
Есть проект Project1. В нем как .cpp, так и .h файлы. В другом проекте Project2 можно просто #include .h файлы из первого проекта и указать получаемую из первого проекта lib в зависимостях.
Однако в .cpp файлах первого проекта есть определение переменных типа:
    
Код:
HANDLE volatile Win32ProcessHeap = 0;
Они же при этом не инклюдятся!

Вот поэтому и нужно компилить не в .dll, а в .lib!!!
Если компилить в .dll, то такие переменные будут в .dll, а в попутно получающейся .lib их не будет. А вот если компилим в .lib, то все будет в ней и из второго проекта прекрасно видно. Вот и выходит, что lib не всегда просто сборище obj...

Что самое интересное - при этом начинают экспортироваться friend операторы, правда все-равно не все. Из трех операторов == видно только первый.

>>Почему остальные нет?

Что удивительно в Debug экспортируется еще и второй оператор == (третьего все-равно не видно). Но что еще более удивительно - хоть они и не видны в экспортируемых, использовать их во втором проекте можно - все прекрасно работает и в Release и в Debug.

>>Каким образом работает, если не видно в экспортируемых?

Смотрел двумя вещами - просто F3 в TotalCommander (выдает заголовок lib), и Dumpbin.

« Последнее редактирование: 19-04-2010 08:28 от seaman » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 19-04-2010 08:45 » 

Ничего не понял. Если lib, то какой и куда экспорт? Если dll, то ничего удивительного в том, что куча проблем при экспорте классов - механизм старый и на классы не рассчитанный.

Экспорт нужен по сути для того, чтобы получить адреса элементов (функций, переменных) внутри dll. И только потому, что dll является уже собранным исполняемым файлом с собственной системой адресации, которая накладывается на адресное пространство процесса при подгрузкие dll.

В lib нет ещё никаких адресов, адреса устанавливаются линкером при сборке. Что куда и зачем экспортировать из lib?

Цитата: seaman
По dll больше инфы - поэтому стал делать ее, тем более, что lib при этом автоматом получается.
По dll больше инфы ровно на столько, на сколько с ней больше геморроя. Улыбаюсь Про lib мало кто пишет, потому что с ней нет никаких проблем (ну кроме всяких inline, templates и т.п. вещей).

Lib, которая получается вместе с dll, на самом деле всего лишь позволяет включить загрузку dll при старте программы, и больше ничего не делает.

Цитата: seaman
Однако в .cpp файлах первого проекта есть определение переменных типа:
   
Код:
HANDLE volatile Win32ProcessHeap = 0;Они же при этом не инклюдятся!
Логично, что модули инкапсулированы. Ну дак вынеси в h-файл с пометкой extern, раз так надо обращаться отовсюду к глобальным переменным.

P.S. Мой совет - лучше выучить матчасть, чем методом тыка получать чудеса вроде экспорта части операторов.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines