Страниц: [1]
  Печать  
Автор Тема: "Дублирование" переменной?  (Прочитано 4731 раз)
GrayCat
Full Member
***
Offline Offline

Сообщений: 128


Gray©at


Просмотр профиля
« : Апреля 21, 2005, 10:43:04 am »

Здравствуйте, товарищи гуру!

Вот, возникла очередная нетривиальная непонятка. Даже не знаю, на что грешить -- компилёр или руки.so . Попробую описать словами, там уже кода не имеющего отношения к проблеме порядочно... Итак, поехали:

Делается свой виджет. Компилируется (из нескольких исходников) в libMyWidget.so. Кроме, собственно, виджета, там заведены еще кое-какие переменные и процедурки, их использующие. Затем в приложении PhAB-а привешиваю к этому виджету коллбэки, в которых, в том числе, используется переменная, объявленная в .SO-шке.

Так вот. Похоже, обращения к одной и той же переменной из процедур в .SO-шке и из коллбэков приложения приводят к работе с разными кусками памяти!

Попробую пояснить:

Заголовок:
// ++++++++++++ MyWidget.h : ++++++++
// ...
extern int Var;
void ModifyVar(void);

Код в исходнике:
// +++++++++++ MyWidget.c : ++++++++
#include "MyWidget.h"
int Var;
void ModifyVar(void)
   {
   Var=0;
   };

Файл с коллбэками в приложении:
// ++++++++++++ MyCallBacks.c +++++++++++++++
...
#include "MyWidget.h"
...
int MyCallback( PtWidget_t *w, void *data, PtCallbackInfo_t *cbinfo )
   {
   Var = 0x55AA;  // Присвоили свое значение
   ModifyVar();   // Здесь Var должна обнулиться!!!
   ...   // ...но при последующем использовании Var
         // остается 0x55AA !!!
   };

Т.е. такое впечатление, что "Var" в библиотеке и "Var" в приложении разные! Нигде в других местах "Var" не объявляется, и, по идее, должно быть глобальным.

Это мое непонимание работы с переменными в разных модулях компиляции, или глюки компилятора?
Записан

Gray©at
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #1 : Апреля 21, 2005, 10:48:57 am »

GrayCat
Это мое непонимание работы с переменными в разных модулях компиляции, или глюки компилятора?

Как собрана .so'шка, какие были опции ?
Записан

MikeP
Участник
*
Offline Offline

Сообщений: 6


Просмотр профиля WWW
« Ответ #2 : Апреля 21, 2005, 11:08:08 am »

Могу только предложить один вариант обхода:
в своей сошке сделать функцию типа int * GetMyVarPointer() и из библиотеки возвращать указатель.
Записан
GrayCat
Full Member
***
Offline Offline

Сообщений: 128


Gray©at


Просмотр профиля
« Ответ #3 : Апреля 21, 2005, 11:23:51 am »

lestat
Как собрана .so'шка, какие были опции ?
Попробую:
qcc PtGenCntr.o Port_Protocols.o ThreadFIFO.o  -Vgcc_ntox86  -shared -Wl,-Bsymbolic -g
 -Bdynamic -l ph -Bdynamic -l phexlib -Bdynamic -l Ap -M -o libPtGenCntr.so
Хмм. Есть подозрение на этот самый "-Bsymbolic", но его настоятельно рекомендует руководство по написанию виджетов.
MikeP
сделать функцию типа int * GetMyVarPointer() и из библиотеки возвращать указатель.
Ну, это самый очевидный путь "Нормальные герои всегда идут в обход!"
Записан

Gray©at
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #4 : Апреля 21, 2005, 11:27:01 am »

GrayCat
Попробую:

А неправильно !!! -fPIC где ?
GrayCat
Нормальные герои всегда идут в обход

Нормальные герои читают мануал по мечу перед тем как махать
Записан

GrayCat
Full Member
***
Offline Offline

Сообщений: 128


Gray©at


Просмотр профиля
« Ответ #5 : Апреля 21, 2005, 01:21:30 pm »

lestat
А неправильно !!! -fPIC где ?
Да, каюсь, забыл. НО! Не помогает! Добавил -fPIC и компилятору, и линкеру -- ничего не меняется...
Записан

Gray©at
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #6 : Апреля 21, 2005, 01:49:50 pm »

GrayCat
Да, каюсь, забыл. НО! Не помогает! Добавил -fPIC и компилятору, и линкеру -- ничего не меняется...


Код lib.c
----------------

unsigned char Var=0xFF;

unsigned char GetVar()
{
   return Var;
}

void SetVar(unsigned char var)
{
   Var=var;
}

----------------

Компилируется так: gcc -shared -fPIC lib.c -o lib.so

Код app.c
----------------

#include <stdio.h>

extern unsigned char GetVar();
extern void SetVar(unsigned char var);
extern unsigned char Var;

int main()
{
   printf("Var=%02X, GetVar=%02X
", Var, GetVar());
   Var=0x55;
   printf("Var=%02X, GetVar=%02X
", Var, GetVar());
   SetVar(0xAA);
   printf("Var=%02X, GetVar=%02X
", Var, GetVar());

   return 0;
}

----------------
Компилируется так: gcc app.c -o app ./lib.so

#./app
Var=FF, GetVar=FF
Var=55, GetVar=55
Var=AA, GetVar=AA

Все так ? Как видно это работает.
Записан

olej
QOR.Team
****
Offline Offline

Сообщений: 42



Просмотр профиля
« Ответ #7 : Апреля 21, 2005, 01:53:00 pm »

Да, каюсь, забыл. НО! Не помогает! Добавил -fPIC и компилятору, и линкеру -- ничего не меняется...

Но уже гораздо ближе: "... уже намазывается, но запах ещё сохраняется..."(с). И так последовательными приближениями...

Хотя, по существу вопроса: довольно ... нелепая конструкция - переменные в динамической библиотеке, к которым доступаемся из вызывающего приложения...
Записан
GrayCat
Full Member
***
Offline Offline

Сообщений: 128


Gray©at


Просмотр профиля
« Ответ #8 : Апреля 21, 2005, 02:08:49 pm »

GrayCat
Есть подозрение на этот самый "-Bsymbolic", но его настоятельно рекомендует руководство по написанию виджетов.
Вот оно. Перепутал сено с соломой. Ключик "-Bsymbolic" добавляется, когда надо из PhAB-приложения сделать .СО-шник. Убрал -- все заработало.

Но все равно -- Спасибо!
Записан

Gray©at
Страниц: [1]
  Печать  
 
Перейти в: