Re[6]: MFC::CString знаешь? ;)
От: MasterZiv СССР  
Дата: 09.09.09 16:53
Оценка: +1
Nik_1 пишет:

> а зачем тогда вообще что-то выносить в длл, а не статически линковать?


А зачем тогда вообще DLL ?

Вот для всего того, для чего нужны DLL, за минусом кроссязыковости.
Posted via RSDN NNTP Server 2.1 beta
Re[8]: MFC::CString знаешь? ;)
От: Erop Россия  
Дата: 09.09.09 17:39
Оценка:
Здравствуйте, Nik_1, Вы писали:

N_>ну дык и я отом же говорю это нужно когда длл может поставляться отдельно от exe, или использоваться в разных приложениях. Но вот тут какраз есть риск что они будут однажды собраны разными компиляторами или с разными настройками.


Ну есть же всякие версии там, манифесты, то сё...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: DLL и <dynamic_cast>
От: Tonal- Россия www.promsoft.ru
Дата: 10.09.09 04:51
Оценка:
Здравствуйте, Frostyland, Вы писали:
F>Отвечаю сразу всем. Спасибо за советы и комментарии.
F>Компилятор от Borland C++ Builder v.6

F>А косяк оказался в наследовании моего базового класса от TObject — суперкласса всех классов VCL.

F>Как только я убрал это наследование — все заработало.
Наследники от TObject должны жить не в dll-ках, а в пакетах.
У багланда есть специальные механизмы под это заточенные.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[6]: DLL и <dynamic_cast>
От: Pavel Dvorkin Россия  
Дата: 10.09.09 06:33
Оценка:
Здравствуйте, byleas, Вы писали:

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


PD>>Все нормально работает

B>А если без declspec?

А тогда непонятно, что ты хочешь. Класс в DLL, но он не экспортируемый. Ты хочешь из EXE получить доступ к неэкспортируемым объектам DLL ? Для простых типов это возможно, но очень нехорошо. А для классов — откуда на стороне EXE возьмут реализацию всех методов класса ?
With best regards
Pavel Dvorkin
Re[7]: DLL и <dynamic_cast>
От: Erop Россия  
Дата: 10.09.09 11:01
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А тогда непонятно, что ты хочешь. Класс в DLL, но он не экспортируемый. Ты хочешь из EXE получить доступ к неэкспортируемым объектам DLL ? Для простых типов это возможно, но очень нехорошо. А для классов — откуда на стороне EXE возьмут реализацию всех методов класса ?


Ну, например, он может быть шаблонным...

А ещё может быть такой код:
if( dynamic_cast<class_from_dll*>( obj ) != 0 ) {
    cout << "Bingo!!!";
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: DLL и <dynamic_cast>
От: Pavel Dvorkin Россия  
Дата: 10.09.09 11:15
Оценка:
Здравствуйте, Erop, Вы писали:

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


PD>>А тогда непонятно, что ты хочешь. Класс в DLL, но он не экспортируемый. Ты хочешь из EXE получить доступ к неэкспортируемым объектам DLL ? Для простых типов это возможно, но очень нехорошо. А для классов — откуда на стороне EXE возьмут реализацию всех методов класса ?


E>Ну, например, он может быть шаблонным...


А что, у нас уже шаблоны в рантайме появились ? Каая мне разница, шаблонный он или нет ?

И подумай еще вот над чем. Если класс экспортируется, то в DLL его дефиниция, а в EXE его декларация. Так что на эапе линковки (через .lib то есть) произойдет связывание их. А если он не экспортируется, то изволь дефиницию делать в EXE. И никто мне в таком случае не мешает завести в EXE класс с тем же именем, но совершенно иным содержанием. Дальнейшее, думаю, понятно.



E>А ещё может быть такой код:
if( dynamic_cast<class_from_dll*>( obj ) != 0 ) {
E>    cout << "Bingo!!!";
E>}


cout << "Ух!!!";
With best regards
Pavel Dvorkin
Re[9]: DLL и <dynamic_cast>
От: Erop Россия  
Дата: 10.09.09 11:31
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А что, у нас уже шаблоны в рантайме появились ? Каая мне разница, шаблонный он или нет ?

В MSVC шаблоны не экспортируются вроде бы...

PD>И никто мне в таком случае не мешает завести в EXE класс с тем же именем, но совершенно иным содержанием. Дальнейшее, думаю, понятно.


Это будет нарушением ODR...

Тем не менее рассмотри, например, такой код:
struct X {
    std::string Text;
};

У неё есть конструктор и деструктор. И, тем не менее, её можно написать в разделяемом Dll и Exe хедере и всё таки будет хорошо...


E>>А ещё может быть такой код:
if( dynamic_cast<class_from_dll*>( obj ) != 0 ) {
E>>    cout << "Bingo!!!";
E>>}


PD> cout << "Ух!!!";

Ну и тем не менее, это валидный код, который ДОЛЖЕН РАБОТАТЬ!!!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: DLL и <dynamic_cast>
От: Pavel Dvorkin Россия  
Дата: 10.09.09 12:15
Оценка:
Здравствуйте, Erop, Вы писали:

PD>>И никто мне в таком случае не мешает завести в EXE класс с тем же именем, но совершенно иным содержанием. Дальнейшее, думаю, понятно.


E>Это будет нарушением ODR...


Это не будет никаким вообще нарушением. Если класс внутренний для DLL (не экспортируемый), то он вообще не есть публичный символ, и я могу при разработке EXE его наличие не учитывать. Соответственно имею право давать именам моих классов какие хочу и о внутренних классах DLL не ндумать, тем более, что я и знать-то не могу, какие они там есть...

E>Тем не менее рассмотри, например, такой код:
struct X {
E>    std::string Text;
E>};

E>У неё есть конструктор и деструктор. И, тем не менее, её можно написать в разделяемом Dll и Exe хедере и всё таки будет хорошо...

Поясни. что в таком случае будет означать "разделяемый Dll и Exe хедере" ? Если то, что в обих случаях будет #include "X.h" — то это ровно ничего не значит. В DLL создается свой класс, в EXE — свой.

Представь себе, что в DLL есть

struct Y {
std::string Text;
int Value;
};

а в EXE — твой X. Хедеры хоть общие , хоть нет — разные совсем классы. Теперь мне во время разработки захотелось из Y это Value выкинуть, а Y переименовать в X. И что ?

E>>>А ещё может быть такой код:
if( dynamic_cast<class_from_dll*>( obj ) != 0 ) {
E>>>    cout << "Bingo!!!";
E>>>}


PD>> cout << "Ух!!!";

E> Ну и тем не менее, это валидный код, который ДОЛЖЕН РАБОТАТЬ!!!

Я так и не понял, откуда тип class_from_dll* взялся без экспорта.
With best regards
Pavel Dvorkin
Re[11]: DLL и <dynamic_cast>
От: Erop Россия  
Дата: 10.09.09 12:28
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

E>>Это будет нарушением ODR...


PD>Это не будет никаким вообще нарушением. Если класс внутренний для DLL (не экспортируемый), то он вообще не есть публичный символ, и я могу при разработке EXE его наличие не учитывать. Соответственно имею право давать именам моих классов какие хочу и о внутренних классах DLL не ндумать, тем более, что я и знать-то не могу, какие они там есть...


В стандарте никаких DLL нет. Есть "программа"... То, что некоторые реализации позволяют прятать часть классов в DLL, фактически вводя связывание промежуточное между внутренним и внешним, это просто особенность этих реализаций...

PD>Поясни. что в таком случае будет означать "разделяемый Dll и Exe хедере" ? Если то, что в обих случаях будет #include "X.h" — то это ровно ничего не значит. В DLL создается свой класс, в EXE — свой.


Значит то, что я могу, например, передать экземпляр этого класса из DLL в EXE, или наоборот... МОгу передать указатель и звать методы, могу работать с полями...


PD>Я так и не понял, откуда тип class_from_dll* взялся без экспорта.

Из хедера...

Экспорт класса всего лишь делает доступным снаружи DLL методы класса...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: DLL и <dynamic_cast>
От: Pavel Dvorkin Россия  
Дата: 10.09.09 13:03
Оценка:
Здравствуйте, Erop, Вы писали:

E>В стандарте никаких DLL нет. Есть "программа"...


Нет. Есть компилируемая и собираемая единица (EXE, DLL). Они независимы вообще-то, так что стандарт применяй к каждой из них. И есть нестандартное расширение — экспорт, и в отношении его действуют правила MS, а не стандарта.

>То, что некоторые реализации позволяют прятать часть классов в DLL, фактически вводя связывание промежуточное между внутренним и внешним, это просто особенность этих реализаций...


А то, что некоторые указатели на классы можно получать вызовом системных функций (COM) — это как в стандарте описано ?


E>Значит то, что я могу, например, передать экземпляр этого класса из DLL в EXE, или наоборот... МОгу передать указатель и звать методы, могу работать с полями...


ИМХО это недопустимо.


PD>>Я так и не понял, откуда тип class_from_dll* взялся без экспорта.

E>Из хедера...

E>Экспорт класса всего лишь делает доступным снаружи DLL методы класса...


Не согласен.
With best regards
Pavel Dvorkin
Re[13]: Приводи примеры реализаций, где ты прав...
От: Erop Россия  
Дата: 10.09.09 18:35
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

E>>В стандарте никаких DLL нет. Есть "программа"...

PD>Нет.
Чего? Покажи мне место в стандарте, где есть термин DLL, пожалуйста. Всюду вроде используется термин programme...
Ну там well formed programme, ill formed programme... Не встерчал?
Кстати, programme без функции main она того, ill formed... Как это, по твоему, вяжется с DLL?

PD>Есть компилируемая и собираемая единица (EXE, DLL).

А как эта "собираемая единица" называется в стандарте? Я давно читал, конечно, лет пять назад, может с тех пор что-то переписали. Но тогда я встречал термин "programme" и термин "translation unit", что ли... А как называется "собираемая единица" я даже и представить не могу. "assembling unit"?

PD>Они независимы вообще-то, так что стандарт применяй к каждой из них. И есть нестандартное расширение — экспорт, и в отношении его действуют правила MS, а не стандарта.

Да? Правда? И где в DLL функция main? Когда она получает управление? В какой взаимосвязи с этой функцией находятся конструкторы и деструкторы глобальных объектов?

>>То, что некоторые реализации позволяют прятать часть классов в DLL, фактически вводя связывание промежуточное между внутренним и внешним, это просто особенность этих реализаций...


PD>А то, что некоторые указатели на классы можно получать вызовом системных функций (COM) — это как в стандарте описано ?


Никак не описано. И DLL и COM и многопоточность -- это расширения стандарта. Он не накладывает на реализацию никаких ограничений по этому поводу. Но реализация сама может накладывать на себя ограничения и давать свои гарантии...

E>>Значит то, что я могу, например, передать экземпляр этого класса из DLL в EXE, или наоборот... МОгу передать указатель и звать методы, могу работать с полями...

PD>ИМХО это недопустимо.

Э-э-э. Я бы ещё понял, "AFAIK", но "IMHO"? При чём тут YHO? Тут, IMHO, намного важнее HO авторов реализации
Я знаю как это сделано на нескольких платформах в нескольких реализациях (SO, Dll, ShLb, оверлеи...)
И везде такое можно... Не затруднит привести реализацию, в которой нельзя?..


PD>>>Я так и не понял, откуда тип class_from_dll* взялся без экспорта.

E>>Из хедера...

E>>Экспорт класса всего лишь делает доступным снаружи DLL методы класса...

PD>Не согласен.
Ну это зависит от реализации, конечно, но это так в MSVC и в MWCW. А вот в SO'шках GCC по умолчанию экспортируется вообще всё. Они в этом смысле намного более похожи на .lib'ы...

Но в известных мне реализациях экспорт класса ничего мистического не делает. Просто экспортирует из DLL/ShLb(из SO по умолчанию всё экспортируют, так что экспорт в явном виде не нужен) методы и статические поля класса...



Но если вернуться к нашему вопросу, что будет, если я в DLL опишу класс одним образом, а в EXE другим, и передам указатель на экземпляр такого класса из DLL в EXE или обратно, то я хотел бы заметить, что С++ так спроектирован, что классы всё равно идентифицируются именно по имени. И именно для того, чтобы не было накладок и требуется, чтобы соблюдалось ODR. А так, нет проблем его нарушить. Смотри:
// shared.h
class SharedClass;
SharedClass* GetHaredClass();
// 1.cpp
#include<shared.h>
class SharedClass {
public:
    int Field1;
    int Field2;
    int Field3;
};

static SharedClass sc;
SharedClass* GetHaredClass() { return &sc; }

// 2.cpp
#include<shared.h>
class SharedClass {
public:
    const char* Ptr() const { return text.c_str(); }
private:
    std::string text;
};

const char* illFormed()
{
    return GetHaredClass()->Ptr();
}
Эта программа будет одинаково некорректна вне зависимости раскидаешь ты 1.cpp и 2.cpp по разным DLL или нет.
И некорректна она будет именно потому, что нарушено ODR...
От реалтзации и раскиданности 1.cpp и 2.cpp по разным DLL зависит только то, сможет ли транслятор заметить нарушение ODR на стадии трансляции или нет. И только...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: Приводи примеры реализаций, где ты прав...
От: Pavel Dvorkin Россия  
Дата: 11.09.09 04:56
Оценка:
Здравствуйте, Erop, Вы писали:

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


E>>>В стандарте никаких DLL нет. Есть "программа"...

PD>>Нет.
E>Чего? Покажи мне место в стандарте, где есть термин DLL, пожалуйста. Всюду вроде используется термин programme...

Не покажу. Нет там DLL. Все это MS Specific. И под MS Specific мы имеем создание проекта, который делает либо EXE, ибо DLL, и каждую из них — компилирует и собирает по отдельности, с учетом требований стандарта. Это то, что мы реально имеем. И если то, что мы реально имеем, противоречит стандарту, то надо работать применительно к реальной ситуации, а не упорно требовать исполнения стандарта. Потому что требовать не от кого, а писать программу надо.

E>Ну там well formed programme, ill formed programme... Не встерчал?




E>Кстати, programme без функции main она того, ill formed... Как это, по твоему, вяжется с DLL?


Еще раз — все это MS Specific.

PD>>Есть компилируемая и собираемая единица (EXE, DLL).

E>А как эта "собираемая единица" называется в стандарте? Я давно читал, конечно, лет пять назад, может с тех пор что-то переписали. Но тогда я встречал термин "programme" и термин "translation unit", что ли... А как называется "собираемая единица" я даже и представить не могу. "assembling unit"?

Называй как хочешь или вообще не называй. Коль скоро этого нет в стандарте, то это нестандартное расширение. А поэтому надо адресоваться не к стандарту, а к Microsoft Specific

PD>>Они независимы вообще-то, так что стандарт применяй к каждой из них. И есть нестандартное расширение — экспорт, и в отношении его действуют правила MS, а не стандарта.

E>Да? Правда? И где в DLL функция main? Когда она получает управление? В какой взаимосвязи с этой функцией находятся конструкторы и деструкторы глобальных объектов?

И опять — все это Microsoft Specific. Про деструкторы и конструкторы, полагаю, знаешь сам — когда они вызываются для глобальных DLL объектов.



E>Никак не описано. И DLL и COM и многопоточность -- это расширения стандарта. Он не накладывает на реализацию никаких ограничений по этому поводу. Но реализация сама может накладывать на себя ограничения и давать свои гарантии...


Столь глубоко философские размышления чужды моему восприятию. Я исхожу из того, что есть реально.

E>>>Значит то, что я могу, например, передать экземпляр этого класса из DLL в EXE, или наоборот... МОгу передать указатель и звать методы, могу работать с полями...

PD>>ИМХО это недопустимо.

E>Э-э-э. Я бы ещё понял, "AFAIK", но "IMHO"? При чём тут YHO? Тут, IMHO, намного важнее HO авторов реализации


. Если можно, приведи мнение авторов реализации насчет того. что это допустимо.


E>Я знаю как это сделано на нескольких платформах в нескольких реализациях (SO, Dll, ShLb, оверлеи...)


Можно конкретный пример, где именно и что сделано. У меня нет времени копаться в исходниках неизвестных мне продуктов.

E>И везде такое можно... Не затруднит привести реализацию, в которой нельзя?..


Да в любой нельзя, если нет экспорта. Потому что это внутренняя структура(класс) DLL. При разработке этой DLL я публикую ее интерфейс, то есть то, что она экспортирует. То, что не экспортирует — не публикую, а стало быть, это никому не должно быть известно. Могу там любые классы и типы внутри определить, как мне захочется. А DLL не есть часть EXE. DLL есть совершенно независимый продукт. И разработчик EXE, используя эту DLL, имеет право пользоваться только опубликованной информацией, и не имеет — непубликуемой. Вот и все. А если какие-то системы публикуют все (хотя я и не пойму, как такое вообще возможно, что там экспортируется, локальные типы тоже ? нет, наверное), значит, все так же, только публикация всего по умолчанию.

А впрочем, можно и проще объяснить. Тебе понятие "файлы символов" знакомо ? Микрософт их распространяет для своих системных DLL, их можно использовать для отладки и т.д. Вот они как раз и содержать всю информацию о внутренних (неэкспортируемых) объектах DLL. Устанавливаешь их на своем компьютере, и можешь трассировать код системных функций на уровне имен/типов. У Фень Юаня так win32k.sys исследуется. Это и есть то, что ты предлагаешь. Только вот одно но — это все только для отладки, в каких бы то ни было продуктах эти файлы никогда не используются, да и вряд ли они вообще redistrivutable.


E>Ну это зависит от реализации, конечно, но это так в MSVC и в MWCW. А вот в SO'шках GCC по умолчанию экспортируется вообще всё. Они в этом смысле намного более похожи на .lib'ы...


Так если экспортируется все, значит, я прав. Только экспорт, но неявный. Ты мне пример приведи, где экспорта нет. Никакого. Есть класс в DLL, и никак он не фигурирует нигде, кроме как в ней самой. А доступ есть.

E>

E>Но если вернуться к нашему вопросу, что будет, если я в DLL опишу класс одним образом, а в EXE другим, и передам указатель на экземпляр такого класса из DLL в EXE или обратно, то я хотел бы заметить, что С++ так спроектирован, что классы всё равно идентифицируются именно по имени. И именно для того, чтобы не было накладок и требуется, чтобы соблюдалось ODR. А так, нет проблем его нарушить. Смотри: [c]// shared.h

<skipped>

Ну не надо так. Программа будет корректна даже без всяких DLL, просто в одном EXE вполне можно описать два различных класса с одним и тем же именем, но разной областью видимости. Чай, не в C# мы все же, типы не глобальны А для DLL мы имеем фактически то же самое , только Microsoft Specific способом. Видимость не на уровне вложенности или static, а на уровне модулей.

Егор, ИМХО наши разногласия в том, что ты упорно требуешь от меня доказательств в соответвствии со стандартом, а я тебе упорно объясняю, что это нестандартное расширение/модификация, а поэтому искать в стандарте ответы на это бессмысленно. Если ты с этим не согласен, то зафиксируем разногласия и закончим дискуссию. Если согласен, то не надо больше ссылок на стандарт, а тогда и можно обсудить, почему из DLL нельзя использовать непубликуемые типы. В соответствии с MS Specific
With best regards
Pavel Dvorkin
Re[7]: DLL и <dynamic_cast>
От: byleas  
Дата: 11.09.09 08:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А тогда непонятно, что ты хочешь.

Я уточнил просто.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.