размещение указателя на таблицу виртуальных ф-й
От: Перфилов  
Дата: 17.06.05 22:23
Оценка:
1. Прописан ли в стандарте механизм реализации вызова виртуальных функций
(в том числе и при множественном наследовании)?

2. Прописано ли в стандарте размещение указателя на таблицу виртуальных
функций (в начале объекта, в конце, или еще где-нибудь)?

Если ничего не прописано, то получается интересная штука. Прежде чем писать
про нее, хотелось бы узнать ответы.
Re: размещение указателя на таблицу виртуальных ф-й
От: Павел Кузнецов  
Дата: 17.06.05 22:46
Оценка:
Перфилов,

> 1. Прописан ли в стандарте механизм реализации вызова виртуальных функций (в том числе и при множественном наследовании)?


Нет (*).

> 2. Прописано ли в стандарте размещение указателя на таблицу виртуальных функций (в начале объекта, в конце, или еще где-нибудь)?


Нет (*).



(*) Более того, даже само наличие таблицы виртуальных функций не требуется.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: размещение указателя на таблицу виртуальных ф-й
От: Перфилов  
Дата: 17.06.05 23:06
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Перфилов,


>> 1. Прописан ли в стандарте механизм реализации вызова виртуальных функций (в том числе и при множественном наследовании)?


ПК>Нет (*).


>> 2. Прописано ли в стандарте размещение указателя на таблицу виртуальных функций (в начале объекта, в конце, или еще где-нибудь)?


ПК>Нет (*).



Я себе вот какую проблему придумал по этому поводу.

Имеем две среды разработки под винду: A и B.
А размецает указатель на таблицу в начале объекта, а B — в конце.
Допустим в среде A я написал dll-ку. Вот h, который поставляется с ней:

// У Foo есть наследники, но пользователь dll о них не знает.
class Foo
{
    friend Foo* CreateFoo(int id);

    private:
    void* pData;

    protected:
    Foo();

    public:
    virtual ~Foo();

    virtual void SomeFunc();
};

Foo* CreateFoo(int id);



Теперь в среде B пытаюсь исп-ть эту dll-ку:
Foo* pFoo = CreateFoo(7);
pFoo->SomeFunc();               // Вот тут по идее должен быть глюк.
Re[3]: размещение указателя на таблицу виртуальных ф-й
От: CrystaX Россия https://crystax.me/
Дата: 18.06.05 06:56
Оценка:
Здравствуйте, Перфилов, Вы писали:

П>Теперь в среде B пытаюсь исп-ть эту dll-ку:

П>
П>Foo* pFoo = CreateFoo(7);
pFoo->>SomeFunc();               // Вот тут по идее должен быть глюк.
П>


Да, именно так все и происходит. Для того, чтобы использовать dll, она должна быть скомпилирована тем же компилятором, что и ее потребитель (для C++, разумеется). Иначе нужно делать интерфейс в виде обычных C функций и описывать их с модификатором extern "C".
Кроме того (даже если у нас нет виртуальных методов в классе), могут возникнуть проблемы с выравниванием. Компиляторы A и B могут по разному расположить члены класса в памяти. Поэтому нужно гарантировать одинаковое выравнивание. Делается это с помощью compiler specific директив, #pragma pack например.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: размещение указателя на таблицу виртуальных ф-й
От: MaximE Великобритания  
Дата: 18.06.05 07:12
Оценка:
On Sat, 18 Jun 2005 03:06:10 +0400, Перфилов <42637@users.rsdn.ru> wrote:

[]

> Имеем две среды разработки под винду: A и B.

> А размецает указатель на таблицу в начале объекта, а B — в конце.
> Допустим в среде A я написал dll-ку. Вот h, который поставляется с ней:

http://rsdn.ru/Forum/?mid=1104199
Автор: MaximE
Дата: 02.04.05


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[3]: размещение указателя на таблицу виртуальных ф-й
От: raskolnikov  
Дата: 18.06.05 09:41
Оценка:
V Knige "Essential COM" (u Anatolix'a byla ran'sche) eta problema dostupno objasnjaetsja.
Dlja etogo COM i sdelan byl.


П>Я себе вот какую проблему придумал по этому поводу.


П>Имеем две среды разработки под винду: A и B.

П>А размецает указатель на таблицу в начале объекта, а B — в конце.
П>Допустим в среде A я написал dll-ку. Вот h, который поставляется с ней:

П>
П>// У Foo есть наследники, но пользователь dll о них не знает.
П>class Foo
П>{
П>    friend Foo* CreateFoo(int id);

П>    private:
П>    void* pData;

П>    protected:
П>    Foo();

П>    public:
П>    virtual ~Foo();

П>    virtual void SomeFunc();
П>};

П>Foo* CreateFoo(int id);

П>



П>Теперь в среде B пытаюсь исп-ть эту dll-ку:

П>
П>Foo* pFoo = CreateFoo(7);
pFoo->>SomeFunc();               // Вот тут по идее должен быть глюк.
П>
Re[4]: размещение указателя на таблицу виртуальных ф-й
От: CrystaX Россия https://crystax.me/
Дата: 18.06.05 09:48
Оценка:
Здравствуйте, MaximE, Вы писали:

Вот в той ветке ты пишешь, что для POD гарантируется одинаковое размещение элементов.
Представим себе такой пример:

struct pod_type
{
    long x;
    short y;
    long z;
};


Вот типичный POD-тип. Теперь предположим, что в компиляторе A sizeof(long) == 4, а в компиляторе B sizeof(long) == 8. Причем еще и выравнивать каждый будет по своему. Какая же здесь может быть гарантия?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: размещение указателя на таблицу виртуальных ф-й
От: Alex Alexandrov США  
Дата: 18.06.05 12:19
Оценка:
Здравствуйте, Перфилов, Вы писали:

П>Теперь в среде B пытаюсь исп-ть эту dll-ку:

П>
П>Foo* pFoo = CreateFoo(7);
pFoo->>SomeFunc();               // Вот тут по идее должен быть глюк.
П>


Глюк будет, можешь быть уверен. К сожалению, Application Binary Interface (ABI) для C++ находится в стадии перманентного зачатия, хотя на *nix стараниями, в том числе, GNU/FSF ситуация получше. В описанном тобой случае глюк появится еще раньше, чем ты думаешь — ты не сможешь слинковаться с DLL, поскольку разные компиляторы манглят имена по-разному и импортные ожидания среды B не совпадут с экспортными возможностями, предоставленными средой A.

Кстати, помимо сложностей с одинаковым декорированием имен и одинаковым бинарным представлением объектов есть и другие:

* Передача владения динамически выделенной памятью трудна. Разные среды имеют, вероятно, разные библиотеки времени исполнения, так что и структуры куч памяти у них, видимо, разные.

* Путешествие исключений. Поддержка раскрутки стека должна быть универсальной, так чтобы при вызове функции на стороне B и генерации там исключения, ты мог это исключение поймать и обработать на стороне A.

И это наверняка не все. В общем, задача весьма непростая и вряд ли осуществимая в ближайшем будущем. Честно говоря, даже не очень в курсе есть ли какие-либо исследовательские разработки в этом плане. Кто-нибудь знает?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Re[5]: размещение указателя на таблицу виртуальных ф-й
От: MaximE Великобритания  
Дата: 18.06.05 13:56
Оценка:
On Sat, 18 Jun 2005 13:48:32 +0400, CrystaX <2315@users.rsdn.ru> wrote:

> Здравствуйте, MaximE, Вы писали:

>
> Вот в той ветке ты пишешь, что для POD гарантируется одинаковое размещение элементов.
> Представим себе такой пример:
>
>
> struct pod_type
> {
>     long x;
>     short y;
>     long z;
> };
>

>
> Вот типичный POD-тип. Теперь предположим, что в компиляторе A sizeof(long) == 4, а в компиляторе B sizeof(long) == 8. Причем еще и выравнивать каждый будет по своему. Какая же здесь может быть гарантия?

На одной платформе это вряд ли случится. Если конечно ты не форсируешь размер типов и выравнивание ключами компилятора.

Возьми, к примеру, хедеры из M$ Platform SDK и сделай по ним поиск "long *". Ты обнаружишь, что немало ф-ций принимают не DWORD*, а именно long*, что говорит о том, что ты не сможешь использовать вместе с этим SDK компилятор, у которого размер long'a отличается от того же размера в M$ компиляторах.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[6]: размещение указателя на таблицу виртуальных ф-й
От: CrystaX Россия https://crystax.me/
Дата: 18.06.05 14:04
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>На одной платформе это вряд ли случится. Если конечно ты не форсируешь размер типов и выравнивание ключами компилятора.


Ну, это-то понятно, что вряд ли. Меня смутила фраза о том, что для POD-типов это гарантируется. Выходит, что нет, не гарантируется.

ME>Возьми, к примеру, хедеры из M$ Platform SDK и сделай по ним поиск "long *". Ты обнаружишь, что немало ф-ций принимают не DWORD*, а именно long*, что говорит о том, что ты не сможешь использовать вместе с этим SDK компилятор, у которого размер long'a отличается от того же размера в M$ компиляторах.


О чем и шла речь выше. Гарантии нет.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[4]: размещение указателя на таблицу виртуальных ф-й
От: Аноним  
Дата: 18.06.05 14:09
Оценка: :)
Здравствуйте, Alex Alexandrov, Вы писали:


AA>И это наверняка не все. В общем, задача весьма непростая и вряд ли осуществимая в ближайшем будущем. Честно говоря, даже не очень в курсе есть ли какие-либо исследовательские разработки в этом плане. Кто-нибудь знает?


.NET?
Re[5]: размещение указателя на таблицу виртуальных ф-й
От: Alex Alexandrov США  
Дата: 18.06.05 17:03
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, Alex Alexandrov, Вы писали:



AA>>И это наверняка не все. В общем, задача весьма непростая и вряд ли осуществимая в ближайшем будущем. Честно говоря, даже не очень в курсе есть ли какие-либо исследовательские разработки в этом плане. Кто-нибудь знает?


А>.NET?


Ха, тебе известны несколько NET-компиляторов разных производителей и случаи их успешной совместной работы? Тогда уж Java больше соответствует этим параметрам. Действительно гибко реализованный ABI.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Re[6]: размещение указателя на таблицу виртуальных ф-й
От: Аноним  
Дата: 18.06.05 20:19
Оценка:
Здравствуйте, Alex Alexandrov, Вы писали:

AA>Здравствуйте, <Аноним>, Вы писали:


А>>Здравствуйте, Alex Alexandrov, Вы писали:



AA>>>И это наверняка не все. В общем, задача весьма непростая и вряд ли осуществимая в ближайшем будущем. Честно говоря, даже не очень в курсе есть ли какие-либо исследовательские разработки в этом плане. Кто-нибудь знает?


А>>.NET?


AA>Ха, тебе известны несколько NET-компиляторов разных производителей и случаи их успешной совместной работы? Тогда уж Java больше соответствует этим параметрам. Действительно гибко реализованный ABI.


Да хоть и Java. Это все частности
Просто это то, как перечисленные тобой проблемы, могут решаться и решаются.
Re[7]: размещение указателя на таблицу виртуальных ф-й
От: Alex Alexandrov США  
Дата: 19.06.05 07:29
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Да хоть и Java. Это все частности

А>Просто это то, как перечисленные тобой проблемы, могут решаться и решаются.

Прошу прощения, но в оригинальном вопросе речь шла о C++ и про наработки именно в области C++. По С++ есть что-нибудь интересное?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Re[8]: размещение указателя на таблицу виртуальных ф-й
От: Cyberax Марс  
Дата: 19.06.05 09:34
Оценка: 5 (1)
Alex Alexandrov wrote:

> А>Да хоть и Java. Это все частности

> А>Просто это то, как перечисленные тобой проблемы, могут решаться и
> решаются.
> Прошу прощения, но в оригинальном вопросе речь шла о C++ и про
> наработки именно в области C++. По С++ есть что-нибудь интересное?

Есть http://www.codesourcery.com/cxx-abi/ — стандарт ABI, который
реализован в GCC и Intel C++. В нем есть и интероперабельность по
исключениям, typeinfo и т.п.

MS его не поддерживает.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[3]: размещение указателя на таблицу виртуальных ф-й
От: SeRya Россия http://home.onego.ru/~ryazanov/
Дата: 20.06.05 07:23
Оценка:
Здравствуйте, Перфилов, Вы писали:

П>Здравствуйте, Павел Кузнецов, Вы писали:


П>Я себе вот какую проблему придумал по этому поводу.


П>Имеем две среды разработки под винду: A и B.

П>А размецает указатель на таблицу в начале объекта, а B — в конце.

Специально для обеспечения двоичной совместимости сделан COM (если ресь идет о Windows) и похожие среды. Я как-то пользовался совместимостью с COM на уровне объектов (а не на уровне DLL), поэтому избавил себя от необходимости регестрироваться в реестре, IDL и прочимих прелестей. В таком случае решение переносимо ровно на столько, на колько переносима библиотека поддержки COM.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.