ZeroCool++
> Хуже реализации чем эта придумать нельзя. Это привязка к определенным компилам, платформам. Почему не сделать как в COM, OpenSL ES?
Это самая универсальная реализация, позволяющая работать с чужими библиотеками напрямую, не делая никаких обвязок для них. Clang и GCC декорируют имена почти одинаково на всех платформах. И отдельную реализацию для студии сделать. Даже до уровня ассемблера опускаться не придётся.
Как в COM - это только через интерфейсы и такой вариант я тоже рассматриваю.
ZeroCool++
> Но мне интересно, как получить адрес конструктора. А эти декорирования имен...
Ну это просто метод с отдельным названием, насколько я понимаю.
ZeroCool++
> Так здесь ООП нужно или что? Сделай си метод, который будет возвращать адрес на
> интерфейс-класс с чисто-виртуальными методами и все.
Нужен максимальный набор фич для моей библиотеки. Интерфейс тоже будет. Сама библиотека может и не будет использовать это всё.
ZeroCool++
> А оператор delete юзается от другой программы. Я например не знаю как delete
> реализуется.
Нет, суть моей идеи в том, что память и выделяется, и освобождается из программы, а не в DLL. Поэтому можно использовать delete и поэтому не нужно определять специальный сишный метод-фабрику.
gammaker
> Это самая универсальная реализация, позволяющая работать с чужими библиотеками
> напрямую
Не позволит
gammaker
> Ну это просто метод с отдельным названием, насколько я понимаю.
А узнать-то его как?
gammaker
> Нет, суть моей идеи в том, что память и выделяется, и освобождается из
> программы, а не в DLL. Поэтому можно использовать delete и поэтому не нужно
> определять специальный сишный метод-фабрику.
Я привел конкретный пример доказывающий обратное:
http://ideone.com/wPFFwo
"Но вот интересная штука. От куда компил достал размер класса с vtable? Возвратил его как скрытый параметр через виртуальный деструктор? Или вызвал другой скрытый виртуальный метод? Или еще что...
Я например не знаю. Где гарантия что delete на другой стороне отработает правильно, если компилить не одной версией компилятора?"
Или проще: delete не просто дергает деструктор, он еще вытваряет всякую магию, которая отличается в разных компиляторах и версий одних и тех же компиляторах, чтобы работали всякие там sized deallocation functions.
Нельзя юзать си пи пи delete, если exe и dll компилились с разными рантаймами, гарантий нет (там не только вызов деструктора и освобождение памяти).
malloc(sizeof(myclass)) не?
ZeroCool++
> А узнать-то его как?
честным способом - никак.
gammaker
> Это самая универсальная реализация, позволяющая работать с чужими библиотеками
> напрямую, не делая никаких обвязок для них.
Не получится. Первая же вражеская библиотека вида:
class Component {...}; // типа как бы экспортируется class Container { std::vector<Component *> cs; public: void AddComponent (Component *pc) { cs.push_back ( pc); } ~Container( ) { for ( unsigned u=0; u<cs.size( ); u++) delete cs[u]; } };
- и использование Component, созданного с подобными ухищрениями, отправит всё начинание в UB.
ZeroCool++
> там не только вызов деструктора и освобождение памяти
Вот об этом я и спрашивал, но мне сначала сказали, что только они. Но думаю, что если не переопределять new/delete для класса, то всё будет норм. Но вообще интересный вопрос, где он берёт смещение. Я думал, что просто operator new запоминает размер блока, но нет. Я проверил -
даже если выделить больше 24 байт, operator delete получает 24.
ZeroCool++
> А узнать-то его как?
Есть некоторые правила, по которым компилятор по прототипу функции однозначно генерирует замангленное имя. Надо просто реализовать эту процедуру манглинга в своей программе и передавать полученное имя в GetProcAddress/dlsym. Но реализовать её придётся минимум 2 раза - для GCC/Clang и MSVC. И возможно ещё придётся учесть некоторые различия на разных платформах.
Sbtrn. Devil
> Не получится. Первая же вражеская библиотека вида:
Я согласен, что получится не всегда. Но если бы например эта вражеская библиотека юзала бы умные указатели, куда можно просунуть свой делитер, проблемы бы не было. Ну а так придётся либо модифицировать библиотеку, либо делать функцию-фабрику.
Я больше рассчитываю на то, чтобы подгружать код, использующий мою библиотеку, а в ней можно проблему переносимости можно как-нибудь решить.
ZeroCool++
> "Но вот интересная штука. От куда компил достал размер класса с vtable?
Из vtbl же и взял. Очевидно, он не может взять его ниоткуда еще да так чтобы не сломать поведение обычного T::delete без параметров.
Фича интересная, но лишь фича (правильному delete лучше игнорировать этот параметр, а работать как обычно) и без виртуальных методов ожидаемо отваливается.
gammaker
> Вот об этом я и спрашивал, но мне сначала сказали, что только они.
Так и есть, там только они.
denesik
> malloc(sizeof(myclass)) не?
Так делать нельзя если потом указатель будет удаляться через delete. Стандарт английским по белому пишет что будет неопределенное поведение.
Тема в архиве.