Re[9]: Представление класса в памяти разными компиляторами
От: Pavel Dvorkin Россия  
Дата: 07.09.10 10:31
Оценка: :)
Здравствуйте, Erop, Вы писали:

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


PD>>Это мелочи, на это есть GetProcAddress


E>А звать как? Например операторы?


Шут его знает. Как-нибудь сформировать указатель на метод-член класса, по нему и вызвать. В крайнем случае через asm.

E>Я бы, лучше, при помощи DEF файла экспортировал из DLL методы сразу под несколькими именами...


Что-то я плохо понимаю. А в EXE как вызывать будем ? С чего это компилятор для, скажем

A* pa = ...;
pa->myfunc();

будет какое-то иное имя, кроме того, что он наманглил, использовать ?
With best regards
Pavel Dvorkin
Re[4]: Представление класса в памяти разными компиляторами
От: Pavel Dvorkin Россия  
Дата: 07.09.10 10:34
Оценка:
Здравствуйте, mike_rs, Вы писали:

_>это то что назвается http://en.wikipedia.org/wiki/Application_binary_interface


когда он есть и стандартизован. В данном случае он не стандартизован.
With best regards
Pavel Dvorkin
Re[10]: Представление класса в памяти разными компиляторами
От: Erop Россия  
Дата: 07.09.10 11:07
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>>Это мелочи, на это есть GetProcAddress

E>>А звать как? Например операторы?
PD>Шут его знает. Как-нибудь сформировать указатель на метод-член класса, по нему и вызвать. В крайнем случае через asm.
О! Это должно быть дико удобно

E>>Я бы, лучше, при помощи DEF файла экспортировал из DLL методы сразу под несколькими именами...

PD>Что-то я плохо понимаю. А в EXE как вызывать будем ? С чего это компилятор для, скажем

PD>A* pa = ...;

pa->>myfunc();

PD>будет какое-то иное имя, кроме того, что он наманглил, использовать ?


Он его и будет. В зависимости от того, какой компилятор компилил EXE будет звать разное имя. Соответственно мы можем экспортировать нужный метод под всеми нужными именами. А под некоторыми можно даже адаптеры экспортировать, на случай, если нет совсем никакого способа объявить класс так, чтобы быть совместимым с каким-то конкретным компилятором, можно ему подсунуть адаптеры...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Представление класса в памяти разными компиляторами
От: Centaur Россия  
Дата: 07.09.10 13:30
Оценка:
Здравствуйте, fanruten, Вы писали:

F>Допустим есть класс экземпляр которого возвращает функция реализованная в dll.


F>Какие гарантии ,что при использование этой dll в коде собранном при помощи компилятора Б, вызов функций членов Foo будет правильный?

F>Ведь как я понимаю различные компиляторы могут по разному представлять экземпляр класса.

Функции-члены классов нельзя вызывать через границу DLL.
К членам-данным не-POD-классов нельзя обращаться через границу DLL.
Экземпляры классов нельзя удалять посредством delete через границу DLL.

Единственное, что можно делать — это передавать туда-сюда указатели на экземпляры. При условии, что вся работа с экземпляром остаётся по одну сторону границы DLL, а по другую стророну это просто обезличенный указатель на чёрный ящик.

COM-объекты можно использовать через границу DLL, при условии, что компиляторы по обе стороны поддерживают COM и все конструкции, употреблённые в описании интерфейса.
Re[2]: Представление класса в памяти разными компиляторами
От: Erop Россия  
Дата: 07.09.10 14:44
Оценка: :))
Здравствуйте, Centaur, Вы писали:

C>Функции-члены классов нельзя вызывать через границу DLL.

C>К членам-данным не-POD-классов нельзя обращаться через границу DLL.
При некоторой ловкости и для известных заранее пар компиляторов можно, тем не менее, но с приложением определённых усилий со стороны DLL, например.

C>Экземпляры классов нельзя удалять посредством delete через границу DLL.

Это да.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Представление класса в памяти разными компиляторами
От: dimchick Украина  
Дата: 11.09.10 07:24
Оценка:
Здравствуйте, Centaur, Вы писали:

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


F>>Допустим есть класс экземпляр которого возвращает функция реализованная в dll.


F>>Какие гарантии ,что при использование этой dll в коде собранном при помощи компилятора Б, вызов функций членов Foo будет правильный?

F>>Ведь как я понимаю различные компиляторы могут по разному представлять экземпляр класса.

C>Функции-члены классов нельзя вызывать через границу DLL.

C>К членам-данным не-POD-классов нельзя обращаться через границу DLL.
C>Экземпляры классов нельзя удалять посредством delete через границу DLL.

C>Единственное, что можно делать — это передавать туда-сюда указатели на экземпляры. При условии, что вся работа с экземпляром остаётся по одну сторону границы DLL, а по другую стророну это просто обезличенный указатель на чёрный ящик.


C>COM-объекты можно использовать через границу DLL, при условии, что компиляторы по обе стороны поддерживают COM и все конструкции, употреблённые в описании интерфейса.


Еще. Классы, в которых есть non-POD типы, должны создаваться/удаляться там, где находится код функций, которые работают с этими классами. Иначе можно нарваться на различное вычисление размера структур и соотв. выделение неправильного объема памяти.
Re[3]: Представление класса в памяти разными компиляторами
От: Vain Россия google.ru
Дата: 13.09.10 17:00
Оценка:
Здравствуйте, Erop, Вы писали:

C>>Экземпляры классов нельзя удалять посредством delete через границу DLL.

E>Это да.
Это почему?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: Представление класса в памяти разными компиляторами
От: Кодт Россия  
Дата: 13.09.10 19:31
Оценка: +1
Здравствуйте, Vain, Вы писали:

C>>>Экземпляры классов нельзя удалять посредством delete через границу DLL.

E>>Это да.
V>Это почему?

В том числе, имеется в виду, "через границу CRT DLL"

Нужно обеспечивать сочетаемость пар operator new-delete и конструктор-деструктор.

"Находятся в одном модуле" — более сильное условие, чем "сочетаемы друг с другом".
Но зато оно более просто проверяемое; не надо задумываться о зависимостях и совместимостях.
Скажем, если инлайновый деструктор обращается к каким-то инлайновым же статическим переменным (классика жанра: std::map) — нехорошо выйдет. А пойди проверь — куда ведут все эти инлайны...
Проще убедиться, что объект удаляется там, где создан, и всё.
Перекуём баги на фичи!
Re[5]: Представление класса в памяти разными компиляторами
От: Vain Россия google.ru
Дата: 13.09.10 21:30
Оценка:
Здравствуйте, Кодт, Вы писали:

C>>>>Экземпляры классов нельзя удалять посредством delete через границу DLL.

E>>>Это да.
V>>Это почему?
К>В том числе, имеется в виду, "через границу CRT DLL"
К>Нужно обеспечивать сочетаемость пар operator new-delete и конструктор-деструктор.
И не только это.

К>"Находятся в одном модуле" — более сильное условие, чем "сочетаемы друг с другом".

К>Но зато оно более просто проверяемое; не надо задумываться о зависимостях и совместимостях.
К>Скажем, если инлайновый деструктор обращается к каким-то инлайновым же статическим переменным (классика жанра: std::map) — нехорошо выйдет.
А какие там статические переменные?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[6]: Представление класса в памяти разными компиляторами
От: Кодт Россия  
Дата: 13.09.10 22:30
Оценка:
Здравствуйте, Vain, Вы писали:

К>>Скажем, если инлайновый деструктор обращается к каким-то инлайновым же статическим переменным (классика жанра: std::map) — нехорошо выйдет.

V>А какие там статические переменные?

За все на свете реализации не поручусь, а в динкумваровской (вижуаловской) — были.
Как известно, мап сделан на КЧД с фиктивными листьями. Так вот, эти листья можно воплотить 4 способами
— трактовать нулевые указатели как указатели на фиктивные листья — это приводит к ветвлениям и просадке производительности
— создать честные листья на куче — затраты памяти
паттерн "нулевой объект"
— — экземпляр фиктивного листа прямо в теле мапа — затраты памяти (увеличение размера мапа); дорогая процедура обмена/присваивания мапов друг с другом (нужно корректировать всё дерево, чтобы гарантировать время жизни листьям)
— — экземпляр фиктивного листа в глобальной переменной
— — можно и пятый способ: разделяемое владение немногими неразличимыми между собой листьями... но это — опять просадка скорости и излишнее усложнение
Перекуём баги на фичи!
Re[7]: Представление класса в памяти разными компиляторами
От: Vain Россия google.ru
Дата: 13.09.10 22:57
Оценка:
Здравствуйте, Кодт, Вы писали:

К>>>Скажем, если инлайновый деструктор обращается к каким-то инлайновым же статическим переменным (классика жанра: std::map) — нехорошо выйдет.

V>>А какие там статические переменные?

К>За все на свете реализации не поручусь, а в динкумваровской (вижуаловской) — были.

К>Как известно, мап сделан на КЧД с фиктивными листьями. Так вот, эти листья можно воплотить 4 способами
К>- трактовать нулевые указатели как указатели на фиктивные листья — это приводит к ветвлениям и просадке производительности
К>- создать честные листья на куче — затраты памяти
К>- паттерн "нулевой объект"
К>- — экземпляр фиктивного листа прямо в теле мапа — затраты памяти (увеличение размера мапа); дорогая процедура обмена/присваивания мапов друг с другом (нужно корректировать всё дерево, чтобы гарантировать время жизни листьям)
К>- — экземпляр фиктивного листа в глобальной переменной
К>- — можно и пятый способ: разделяемое владение немногими неразличимыми между собой листьями... но это — опять просадка скорости и излишнее усложнение
А почему бы просто в корне не хранить? Или я что-то недопонял?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[8]: Представление класса в памяти разными компиляторами
От: Кодт Россия  
Дата: 14.09.10 08:01
Оценка:
Здравствуйте, Vain, Вы писали:

V>А почему бы просто в корне не хранить? Или я что-то недопонял?


В любом случае, это будет оверхед — по сравнению со статическим расшаренным объектом.

На самом деле, суть бага в том, что признак "это фиктивный лист" выводился не из того, что "это лист", а "адрес этого объекта равен адресу нашего синглетона". Эта проверка более дешёвая, но не выдерживает испытания многомодульностью (и нарушением ODR, на самом деле: ибо, у нас появляются несколько экземпляров статической переменной).
Перекуём баги на фичи!
Re[9]: Представление класса в памяти разными компиляторами
От: Vain Россия google.ru
Дата: 14.09.10 17:40
Оценка: :)
Здравствуйте, Кодт, Вы писали:

V>>А почему бы просто в корне не хранить? Или я что-то недопонял?

К>В любом случае, это будет оверхед — по сравнению со статическим расшаренным объектом.
К>На самом деле, суть бага в том, что признак "это фиктивный лист" выводился не из того, что "это лист", а "адрес этого объекта равен адресу нашего синглетона". Эта проверка более дешёвая, но не выдерживает испытания многомодульностью (и нарушением ODR, на самом деле: ибо, у нас появляются несколько экземпляров статической переменной).
Как я понимаю, дерево в реализации STL это технически тот же самый лист (т.к. STL требует линейной итерируемости от любого контейнера), т.е. ноды не перемещаемы в памяти, а т.к. минимум корень всегда будет существовать при хотябы одном листе, то это и есть нормальное решение. А неявные статические переменные в контейнерах и указатели на тело объекта в нодах это — от лукавого.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: Представление класса в памяти разными компиляторами
От: achp  
Дата: 14.09.10 18:46
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Можно проверить поддерживает ли данный компилятор COM или нечто аналогичное.

CS>Если "да" то в принципе можно делать предположения об однообразии. А лучше прямо COM интерфейсы и писать.

Насколько я могу припомнить, в COM нигде структурами данных не обмениваются. COM полагается только на способ размещения vptr и способ организации vtbl.
Re[10]: Представление класса в памяти разными компиляторами
От: Кодт Россия  
Дата: 15.09.10 07:33
Оценка:
Здравствуйте, Vain, Вы писали:

V>Как я понимаю, дерево в реализации STL это технически тот же самый лист (т.к. STL требует линейной итерируемости от любого контейнера), т.е. ноды не перемещаемы в памяти, а т.к. минимум корень всегда будет существовать при хотябы одном листе, то это и есть нормальное решение. А неявные статические переменные в контейнерах и указатели на тело объекта в нодах это — от лукавого.


Технически это всё-таки дерево. Полный обход дерева — за O(n), а одна итерация занимает переменное время.
Фиктивный корень, подобно фиктивным концам списка, у дерева тоже есть и является принадлежностью конкретного контейнера. Это end().
А фиктивные листья несут два признака: цвет:чёрный и лист:да.

Сейчас посмотрел на реализацию в VC8, там фиктивные листья совпадают с фиктивным корнем. Который тоже чёрный и пустой.
То есть, граф такого дерева выглядит вот так
            _
           / \
         end  \
        /   \_/\
       4        \
    __/ \__      \
   2       6      \
  / \     / \      \
 1   3   5   7     /
/ \ / \ / \ / \   /
\__\\__\\__\\__\_/

А в VC7 ещё, насколько я помню, было со статическими листьями.
Перекуём баги на фичи!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.