Неявное использование объекта определенного в библиотеке
От: Prozaick  
Дата: 03.01.03 18:01
Оценка:
//в либе есть файл с текстом
class A
{
...
} a;
//допустим, что кроме этого в либе ничего нет

/*
В конструкторе A() происходит обращение к статическим функциям основного модуля. Не 
хотелось бы вдаваться в подробности, или обсуждать
целесообразность подобных связей.

Проблема состоит в том, что объект "a" не
создается, а следовательно, не вызывается 
конструктор. Если в этот модуль добавить
функцию, и вызвать ее из основного, то объект
будет создан. Нельзя ли обойтись без функции.
Может быть есть какая-нибудь прагма или что-то в этом роде.

P.S. 
Объявление класса А в основной модуль включать нельзя.
*/
Re: Неявное использование объекта определенного в библиотеке
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 03.01.03 18:10
Оценка:
Хотел написать ответ, но меня, как всегда, опередили Вот отличный ответ Павла Кузнецова
Автор: Павел Кузнецов
Дата: 09.09.02
, описывающий решение этой проблемы.
Алексей Кирдин
Re: Неявное использование объекта определенного в библиотеке
От: vvs86 Великобритания  
Дата: 03.01.03 18:59
Оценка:
A chto esli v zagolovochnom fajle objavit klass tak — eto skoree vopros chem otvet.
Prostite za NEkirilicu.

class CSomeClass;
Re[2]: Неявное использование объекта определенного в библиот
От: Андрей Тарасевич Беларусь  
Дата: 03.01.03 19:09
Оценка:
Здравствуйте, Kaa, Вы писали:

Kaa>Хотел написать ответ, но меня, как всегда, опередили Вот отличный ответ Павла Кузнецова
Автор: Павел Кузнецов
Дата: 09.09.02
, описывающий решение этой проблемы.


Что-то я не совсем понимаю. А с каких пор это стало проблемой? Если единица компиляции компилируется в составе программы, то определенный в ней объект обязан рано или поздно конструироваться. Для этого не надо принимать никаких дополнительных мер. Или речь идет о каком-то конкретном специфическом компоновщике, который позволяет себе такие вольности, как выкидывание объектников без явных внешних имен?
Best regards,
Андрей Тарасевич
Re[2]: Неявное использование объекта определенного в библиот
От: kmn Украина  
Дата: 04.01.03 08:19
Оценка:
Здравствуйте, Kaa, Вы писали:

Kaa>Хотел написать ответ, но меня, как всегда, опередили :-)) Вот отличный ответ Павла Кузнецова
Автор: Павел Кузнецов
Дата: 09.09.02
, описывающий решение этой проблемы.


А что делать, если у меня объявление и реализация класса в .cpp файле?

P.S. если этот механизм использовать в exe или dll, то все прекрасно работает.
Re[3]: Неявное использование объекта определенного в библиот
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 04.01.03 10:32
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Или речь идет о каком-то конкретном специфическом компоновщике, который позволяет себе такие вольности, как выкидывание объектников без явных внешних имен?


По крайней мере, VC6 себе такое позволяет. Вот пример, воспроизводящий (как мне кажется) ситуацию:

Файлы библиотеки lib (3 штуки, статическая либа):
# ifndef _aaa_library_h_
#   define _aaa_library_h_

//[] library.h - public header

// Какой-то контент
class LibServer
{
public:
        LibServer();
  void  AddRef  ();
  long  Release ();

private:
  long nRefs;
};

// Макрос, решающий проблему
# define USE_LINKLIB
# ifdef USE_LINKLIB

class LinkLib
{
public:
  LinkLib();
};

// Фиктивный объект
const LinkLib link_lib;

# endif // USE_LINKLIB
 
# endif // _aaa_library_h_


//[] initlib.h - private header

// Некая функция из основной программы вне этой либы
extern long& Refs();

struct InitLib
{
  InitLib()
  {
    ++Refs(); // её использование
  }
};


//[] library.cpp
# include "library.h"
# include "initlib.h"

InitLib initLib; // Выкинутый объект (вернее, вызов конструктора)

LibServer::LibServer() 
  : nRefs( 0 ) 
{
}

void  LibServer::AddRef  () { ++nRefs; }
long  LibServer::Release () 
{ 
  long n = --nRefs; 
  if ( ! n ) 
    delete this; 
  return n; 
}

# ifdef USE_LINKLIB
LinkLib::LinkLib()
{
  InitLib& r = initLib; // Насильный вызов конструктора
}
# endif


Главный файл приложения:
//[] main.cpp - к нему линкуется статическая либа
# include <stdio.h>
# include "lib/library.h"

long& Refs() 
{ 
  static long refs = 0; 
  return refs; 
}

int main()
{
  printf( "Refs() erturns %d\n", Refs() );
  return 0;
}



В случае правильно отработавшего кода (с определенным макросом USE_LINKLIB) printf должен выводить 1, а в неправильном — 0.
Алексей Кирдин
Re[3]: Неявное использование объекта определенного в библиот
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 04.01.03 10:39
Оценка:
kmn>А что делать, если у меня объявление и реализация класса в .cpp файле?

Того, чей конструктор не вызвался? Это не важно. Схема та-же. Надо объявить фиктивный класс, фиктивный объект этого класса в заголовка библиотеки, реализовать его в cpp-шнике, и из его конструктора дергать тот объект, для которого не делается вызов конструктора.
Алексей Кирдин
Re[4]: Неявное использование объекта определенного в библиот
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 04.01.03 11:07
Оценка:
Kaa>VC6 себе такое позволяет.
Проверил с mingw 3.1 (кто там у него линкером подрабатывает). То же самое.
Алексей Кирдин
Re[4]: Неявное использование объекта определенного в библиот
От: Prozaick  
Дата: 05.01.03 13:01
Оценка:
Здравствуйте, Kaa, Вы писали:

Kaa>По крайней мере, VC6 себе такое позволяет. Вот пример, воспроизводящий (как мне кажется) ситуацию:


Спасибо за совет. Хотя пример с фиктивным объектом мне не очень подходил, я использовал этот прием немного изменив свой код. Тем не менее, думаю вы согласитесь, что это не лучшее решение. Как, например, быть если в либе более одного сабжевого обжа? Предложите плодить различные конструкторы . Мне кажется проблема решается каким нибудь ключом линкера. В любом случае спасибо, что откликнулись.


Жить без извращений нам никак нельзя ...

Re[3]: Неявное использование объекта определенного в библиот
От: Prozaick  
Дата: 05.01.03 13:16
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Что-то я не совсем понимаю. А с каких пор это стало проблемой? Если единица компиляции компилируется в составе программы, то обпереденный в ней объект обязан рано или поздно конструироваться. Для этого не надо принимать никаких дополнительных мер. Или речь идет о каком-то конкретном специфическом компоновщике, который позволяет себе такие вольности, как выкидывание объектников без явных внешних имен?


Речь идет о компоновщике VC++60. На мой взгляд, компоновщик не выкидывает объект из либа, но выкидывает обж. И мне кажется это сделано с очевидной целью — для уменьшения объема. Отмечу, что я не включал оптимизацию кода по размеру.


Жить без извращений нам никак нельзя

Re[4]: Неявное использование объекта определенного в библиот
От: Андрей Тарасевич Беларусь  
Дата: 06.01.03 23:58
Оценка:
Здравствуйте, Kaa, Вы писали:

АТ>>Или речь идет о каком-то конкретном специфическом компоновщике, который позволяет себе такие вольности, как выкидывание объектников без явных внешних имен?


Kaa>По крайней мере, VC6 себе такое позволяет.


Да, проверил. Действительно, безобразие имеет место быть.
Best regards,
Андрей Тарасевич
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.