URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 1952
[ Назад ]

Исходное сообщение
"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна помощь"

Отправлено Оленини Владимир , 06-Авг-03 12:21 
Вот собственно subj. только просьба не опускать и не говорить что
это никому не надо. Лучше предлагать дельные советы или помощь.

На всякий случай объясняю:
COM - это способ избежать проблемы возникающей при динамической
линковке бтблиотек содержащих классы или структуры изменяющиеся
(это важно) от версии к версии.
Возникающие проблемы - смещение адресов данных и идентификаторов
vtable.

COM версии M$ пошел простым путем - просто запретил изменять
интерефы после release'a. Я решил сделать по другому.

Пришел к выводу что нужен свой язык (близкий к C++) чтобы все
работало нормально (без интерфейсов) и с нормальным наследованием.
Основа написана - создает C (не C++) код который можно потом
уже любым компилятором собрать. Есть баги и проблемы но уже
(по крайней-мере) полученный код запускается.

Но работа еще далека от завершения:
- разобраться с циклическими ссылками
(в перл'е :  $a={};$b={};$a->{b}=$b;$b->{a}=$a; - такая
структура не удалятся из памяти)
- шаблоны ? - понятия не имею как их _нормально_ реализовать.
- массивы (Есть vector который хранит любой объект а хочется
аналог my_class**array )
- Сама стандартная библиотека ;)

Поэтому очень надеюсь на вашу помощь.

Пишите сюда и на vahvarh@rbcmail.ru - буду признателен.


Содержание

Сообщения в этом обсуждении
"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Soldier , 06-Авг-03 14:13 
>На всякий случай объясняю:
>COM - это способ избежать проблемы возникающей при динамической
>линковке бтблиотек содержащих классы или структуры изменяющиеся
>(это важно) от версии к версии.
>Возникающие проблемы - смещение адресов данных и идентификаторов
>vtable.

Прошу прощения за отсутствие дельных советов, но мне кажется, что эти проблемы достаточно просто решаются под  Linux (думаю и под другими *n*x тоже). Несколько упрощенно: необходимые методы классов объявляются virtual, пишется специальная функция, отвечающая за инициализацию класса. Далее динамически грузим либу с классом, инициализируем класс с помощью той самой специальной функции  из этой либы и пользуем виртуальные методы этого класса по полной программе.


"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Оленини Владимир , 06-Авг-03 14:23 
>Прошу прощения за отсутствие дельных советов, но мне кажется, что эти проблемы
>достаточно просто решаются под  Linux (думаю и под другими *n*x
>тоже). Несколько упрощенно: необходимые методы классов объявляются virtual, пишется специальная функция,
>отвечающая за инициализацию класса. Далее динамически грузим либу с классом, инициализируем
>класс с помощью той самой специальной функции  из этой либы
>и пользуем виртуальные методы этого класса по полной программе.

Если с самого начала:

Версия 1.0
class A {
A();
virtual m1();
};
class B: public A {
B();
virtual m3();
};
Итого:
идентификатор m1 - 0
идентификатор m3 - 1

Версия 2.0
class A {
A();
virtual m1();
virtual m2();
};
class B: public A {
B();
virtual m3();
};
Итого:
идентификатор m1 - 0
идентификатор m2 - 1
идентификатор m3 - 2


А внутри программы сами идентификаторы методов хранятся
по номерам - соотв программа скомпиленная с v1.0 в версии
v2.0 запустит A::m2() вместо B::m3().
Это _основная_ проблема несовместимости библиотек.
Решения:
M$ (COM,IDL) - запретить изменение на фиг.
CORBA (IDL) - то же самое
CORBA (ISL?) - вызов по имени ( ->call("printf",....) - очень медленно)
BeOS - сделать virtual void unused_1() - virtual void unused_30()
и постепенно их заменять и переименовывать.


"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Soldier , 06-Авг-03 16:00 
>Если с самого начала:
...
А если немного подругому:
v1:
class A {
public:
  A() {;}
  virtual void m1()=0;
};

class B: public A {
public:
B() {;}
virtual void  m1();
};

typedef bool ( *P_FN_INIT_A )( A ** ); //Для инициализатора класса

v2:
class A {
public:
  A() {;}
  virtual void m1()=0;
  virtual void m3()=0;
};

class B: public A {
public:
B() {;}
virtual void  m1();
virtual void  m3();
};

typedef bool ( *P_FN_INIT_A )( A ** ); //Для инициализатора класса

Инициализатор в обоих версиях имеет вид:
extern "C" bool DlInitClassA( A **ppClassA ) {
    if ( *ppClassA ) return false;
    *ppClassA = new B;
    return true;
}


В основной проге:
Определяем:
P_FN_INIT_A pfnDlInitA = NULL;
void *pDl;
A *pMyClass = NULL;

Через dlopen грузим инициализатор, с его помощью инициализируем класс:

pDl = dlopen(LIB_PATH, RTLD_LAZY);
pfnDlInitA = ( P_FN_INIT_A)dlsym( pDl, "DlInitClassA" );
pfnDlInitA( &pMyClass );

pMyClass->m1();

Все - независимо от либы вызывается метод m1 класса B

?


"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Оленини Владимир , 06-Авг-03 16:24 
>pDl = dlopen(LIB_PATH, RTLD_LAZY);
>pfnDlInitA = ( P_FN_INIT_A)dlsym( pDl, "DlInitClassA" );
>pfnDlInitA( &pMyClass );
>
>pMyClass->m1();
>Все - независимо от либы вызывается метод m1 класса B

Ага а теперь дабавь и в первую и во вторую версию метод
B::m2() ( но без A::m2() ) и попробуй вызови его в версии где
появился A::m3() ...
Ну dynamic_cast<B*>(pMyClass)->m2()
Вызовется A::m3


"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Soldier , 06-Авг-03 16:39 
>>pDl = dlopen(LIB_PATH, RTLD_LAZY);
>>pfnDlInitA = ( P_FN_INIT_A)dlsym( pDl, "DlInitClassA" );
>>pfnDlInitA( &pMyClass );
>>
>>pMyClass->m1();
>>Все - независимо от либы вызывается метод m1 класса B
>
>Ага а теперь дабавь и в первую и во вторую версию метод
>
>B::m2() ( но без A::m2() ) и попробуй вызови его в версии
>где
>появился A::m3() ...
>Ну dynamic_cast<B*>(pMyClass)->m2()
>Вызовется A::m3

Не допонимаем мы друг-друга что-ли... Изменил так:

v1:
class A {
public:
  A() {;}
  virtual void m1()=0;
};

class B {
public:
B() {;}
virtual void  m1();
virtual void  m2();
};

v2:
lass A {
public:
  A() {;}
  virtual void m1()=0;
  virtual void m3()=0;
};

class B {
public:
B() {;}
virtual void  m1();
virtual void  m2();
virtual void  m3();
};

A -БАЗОВЫЙ КЛАСС. Работаем с B!
B->m2()  вызывается в соответсвии с либой

???


"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Soldier , 07-Авг-03 10:37 
Я был не прав...
Удачи

"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Оленин Владимир , 07-Авг-03 10:41 
>Я был не прав...
>Удачи
А я уже начал с испугу писать пример (я же до этого в GDB в асме
все проверял и тут ты говоришь что оно должно работать хотя я
знаю что не может).

Ты бы хоть чем, написал бы что-нить, вступил бы в коллектив разработчиков :)


"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Soldier , 07-Авг-03 14:09 
>>Я был не прав...
>>Удачи
>А я уже начал с испугу писать пример (я же до этого
>в GDB в асме
>все проверял и тут ты говоришь что оно должно работать хотя я
>
>знаю что не может).

Да упаренный я вчера был слегка :)


>Ты бы хоть чем, написал бы что-нить, вступил бы в коллектив разработчиков
>:)
Сомневаюсь, что я чем-то смогу помочь :)



"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Оленин Владимир , 07-Авг-03 14:18 
>>Ты бы хоть чем, написал бы что-нить, вступил бы в коллектив разработчиков
>Сомневаюсь, что я чем-то смогу помочь :)
Ну почему же - ты разве C не знаешь? Все что нужно это
знание C, bison (опционально) полет мысли и некоторое кол-во
свободного времени ;)

На самом деле большая часть языка написана - нужно писать стандартную
библиотеку - работа с фалами, потоками, сокетами, GUI, и все прочее...


"Пишу аналог COM для Linux/Unix/Etc только нормальный - нужна..."
Отправлено Soldier , 08-Авг-03 07:15 
>>>Ты бы хоть чем, написал бы что-нить, вступил бы в коллектив разработчиков
>>Сомневаюсь, что я чем-то смогу помочь :)
>Ну почему же - ты разве C не знаешь? Все что нужно
>это
>знание C, bison (опционально) полет мысли и некоторое кол-во
>свободного времени ;)

Вот с последним у меня как раз баальшая проблема :)