LINUX.ORG.RU

глоб. переменная всей программы в библиотеке ?


0

0

Не могу понять как сделать а как делаю не получается. :((
Подскажите как правильно или как сделать чтоб работало.
Есть 3 файла.
1. main.cpp
2. lib.cpp, lib.h
3. dll.cpp -> libtest-dll.so

код 'lib.cpp' - разделяемый, но он пока не оформлен в виде 
разделяемой библиотеки.

Этот код необходимо включить в разделяемую библиотеку, так как
 в ней происходят системные вызовы из 'lib.cpp'

'lib.cpp' - используется и в  main.cpp.
В main.cpp объявлена глобальная переменная

Мне нужно собрать программу так чтоб 
libtest-dll.so поняла, что :
1. есть глобальная переменная
2. прошла линковка
3. при запуске программы отработали вызовы
   записи из библиотеки через вызовы 'lib.cpp'.

Я включил статически код 'lib.cpp' в dll.cpp и собрал разделяемую
библиотеку - libtest-dll.so
но при запуске программы у меня выдается ошибка:
'no open lib: './libtest-dll.so', error:'./libtest-dll.so: 
undefined symbol: gl_pShareObject'

Не могу понять где я делаю что неправильно.
Может  'lib.cpp' нужно оформить в виде
 разделяемой библиотеки  'lib.so'
а ее уже подключать к dll.cpp при статической линковки
при получении  libtest-dll.so ?
Подскажите пожалуйста сли не сложно.
  
Для примера набрал приблизительный код.

=================================
//main.cpp
...
#include "lib.h"

clShare * gl_pShareObject;

void main(void)
{
   pShare = new clShare;
   ...
   // Загрузка библиотеки
   // Получение указателя на нужную функцию из библиотеки
   if (fork()==0) 
   {
     // запуск нужной ф-ции из библиотеки
     //  используя полученный указатель на эту функцию
   } //

   char buf[40];
   gl_pShareObject->FnRead(buf);

} // main()

================================
//lib.h
class clShare 
{
...
public:
int FnRead(char * buf);
int FnWrite(char * buf);
};
--
//lib.cpp
...
#include "lib.h"
int clShare::FnRead(char * buf)
{ ...  return  1; }
int clShare::FnWrite(char * buf)
{ ...  return  1; }

================================
//dll.cpp  -> libtest-dll.so
extern clShare * gl_pShareObject;

void Function_DLL(void)
{  char buf[40];
   gl_pShareObject->FnWrite(buf);
}
==================================
anonymous

Ответ на: комментарий от ananas

Эта переменная должна быть видна в основной программе.
И эта переменная не должна выгружаться вместе с библиотекой.
Правда наверное ее можно туда передать как параметр. Не знаю.
Но хотелось бы решить этот вопрос именно с помощью
правильной линковки, размещения кода и правильно собранных библиотек.
Почему именно так - чтоб не зависить от частного случая.
Вообще я не совсем понимаю как в таких случаях поступать.
Ведь в самой Linux - наверняка такие вещи встречаются. 

anonymous
()
Ответ на: комментарий от ananas

Глобальную переменную нужно размещать в разделяемой библиотеке, чтобы
она была видна екзешнику и самой библиотеке. Если не хочешь, чтобы
она пропадала с выгрузкой твоей libtest-dll.so, почему бы не сделать
еще одну библиотеку, содержащую только эту переменную и, возможно,
какие-то вспомогательные функции:

libShareObject.so:

----------------
#include ....
clShare * gl_pShareObject;
.........
----------------

?

jek_
()
Ответ на: комментарий от jek_

Да я подумывал именно об этом - спасибо.

Но тогда встает вопрос с линковкой и видимостью переменной. 
Я хотел линковать саму прогу с 'libShareObject.so' 
Библиотеку  'libtest-dll.so' с  'libShareObject.so' то-же хотел линковать.

Но 'libtest-dll.so'  с самой прогой не линкуется а загружается динамически
руками с помощью dlopen() и т.д.

И тогда не очень понятно как все там внутри будет
разберется ли загрузчик, что 'libShareObject.so' в одном экземпляре
и правильно ли произойдет динамическое связывание.

Моя глобальная переменная, код которой описан в libShareObject.so' 
инициализируется в теле самой проги (main),
и объявляется  как  " extern clShare * gl_pShareObject; "
в теле 'libtest-dll.so'.

После загрузки 'libtest-dll.so' из  main 
Функци из подгруженной библиотеки будут правильно видеть
" extern clShare * gl_pShareObject; "   ??

anonymous
()
Ответ на: комментарий от anonymous

Слинкуй твой executable и libtest-dll.so с libShareObject.so.
В них обоих объяви extern clShare * gl_pShareObject.
libShareObject.so загрузится автоматически с загрузкой executable.
Переменная gl_pShareObject будет использована и в нем и в 
libtest-dll.so. Будет она в единственном экземпляре. То есть вообще
ни о чем не нужно заботиться - все будет делаться автоматически.

jek_
()
Ответ на: комментарий от jek_

Немного невнятно получилось. Надо так:

//dll.cpp  -> libtest-dll.so
.....................
extern clShare * gl_pShareObject;
.....................

//main.cpp -> executable
.....................
extern clShare * gl_pShareObject;
.....................

//SharedObject.cpp -> libSharedObject.so
.....................
clShare * gl_pShareObject;
.....................

Сборка:

gcc -shared SharedObject.cpp -o libSharedObject.so
gcc -shared dll.cpp -o libtest-dll.so libSharedObject.so
gcc main.cpp -o main libSharedObject.so

Всё.

jek_
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.