информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медSpanning Tree Protocol: недокументированное применение
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
[C++] Это очень страшно. 27.09.03 18:09  Число просмотров: 1415
Автор: Tlo Статус: Незарегистрированный пользователь
<"чистая" ссылка>
(Ох, как вспомню как я бился с dll'ками, статически линкуемыми с MFC, страшно становиться).

Теперь немного по делу. Если ты принимаешь правила framework'а. то принимаешь их полностью. Поэтому, если тебе говорят, что переключать контексты надо во всех экспортируемых, то надо их переключать. А иначе придется делать заключения ореализацииклассов famework'а (так как ты, безусловно корректно, сделал для CString), что не всегда возможно, особенно, если хост и dll'ка собраны с разными версиями билдами MFC (не говоря уже о разных версиях).

Но это все баблинг (и наверное, void, все-таки не для тебя, а для менее искушенных). А что касается непосредственно AFX_MODULE_STATE, то если не ошибаюсь он хранит только инфу, необходимую для mfc'овых хуков - любые функции dll, создающие окна, например те, которые работают с mfc'овыми CAsyncSocket'ами (отгадайте почему :), должны переключить контекст -, и что-то там с DAO.

Здравый же смысл, действительно подсказывает, что тривиальные функции, неимеющие сношений с MFC не должны переключать контекст модулей (операция, прямо скажем сама по себе нетривиальная). Но опять-таки подчеркну свое imho (входящее в резонанс с mfc'овым ho) - если framework навязывает - надо выполнять. Это как с параметрами операций типа IUnknown - можно AddRef не делать - и так работать будет, но это уже отклонение от стандарта, и вся ответственность лежит уже на вас.

Ничего нового, конечно, но может поможет.
<programming>
[c++] afx_manage_state – всегда ли? 25.09.03 06:39  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Возможно, из-за недостатка моего опыта вопрос покажется очень простым,
но прошу не отсылать к MSDN. Там я не нашёл однозначного ответа «на все случаи жизни».

Вопрос в том, собственно, а всегда ли необходимо использовать этот макро в Regular DLL MFC?

1) DLL изготавливается не с «uses the shared MFC libraries», a «statically linked MFC».
Есть подозрение, что в этом случае AFX_MANAGE_STATE не нужен вовсе. Так ли?

2) Практически во всех статьях MSDN сказано, что если «shared MFC libraries», то используйте AFX_MANAGE_STATE во всех экспортируемых функциях (я бы поправил здесь писателей от мелкософт – не экспортируемых, а вызываемых).

Но так ли?

Положим, есть класс в «Regular DLL MFC whis shared MFC libraries»:

class CI_ODBCquery: public IQueryInterface { private: CRecordset* Query; … … CString connection; CString error; LPCTSTR error2; bool msgerror; public: void __stdcall Connection (LPCTSTR ConnectionStr); void __stdcall CanErrorMessage(const int can_msg); void __stdcall ErrorMessage (LPTSTR* outval ); void __stdcall ErrorMessage2 (LPTSTR* outval ); … … };

Четыре функции в конце декларации класса CI_ODBCquery доступны программисту для вызовов после «загрузки» DLL, т.е. программист вызывает эти функции DLL непосредственно.

Функция CanErrorMessage(const int can_msg) совсем простая. Она устанавливает msgerror в true/false:

void __stdcall CI_ODBCquery::CanErrorMessage(const int can_msg) { msgerror = can_msg ? true:false; }

Спрашивается, ну зачем здесь что-то «синхронизировать» в MFC при помощи макро AFX_MANAGE_STATE? Думаю, не требуется макро AFX_MANAGE_STATE. Так?

Функция ErrorMessage2(LPTSTR* outval ) – не сложнее. Она только «возвращает» указатель на нуль-терминированную строку error2:

void __stdcall CI_ODBCquery::ErrorMessage2(LPTSTR* outval) { *outval = error2; }

Не требуется макро AFX_MANAGE_STATE. Так?

Функция ErrorMessage(LPTSTR* outval ) – чуть «сложнее». Она «возвращает» указатель на нуль-терминированную строку – буфер класса MFC CString error:

void __stdcall CI_ODBCquery::ErrorMessage1(LPTSTR* outval) { *outval = (LPTSTR)((LPCTSTR)error); }

Здесь, как бы и самое место тому AFX_MANAGE_STATE, поскольку речь идёт об непосредственном обращении к объекту error класса MFC CString. Но!!! Переменная error была инициализирована, а потом возможно «перезаписана» неоднократно совершенно из других приват-функций класса CI_ODBCquery. Сомнительно, что и здесь следует использовать AFX_MANAGE_STATE. Так?

С функцией Connection (LPCTSTR ConnectionStr), см. выше, возможно дело чуть сложнее, поскольку из её тела происходит «перераспределение» памяти, используемой, переменной CString connection:

void __stdcall CI_ODBCquery::Connection(LPCTSTR ConnectionStr) { connection = _TEXT("DSN="); connection += ConnectionStr; connection += _TEXT(";UID=;PWD="); … … }

Казалось бы, что раз мы «напрямую» задействуем MFC CString «из вне», то наличие AFX_MANAGE_STATE просто обязательно. Но!!! Переменная connection была инициализирована пустой строкой в конструкторе CI_ODBCquery до того, как программист может сделать вызов Connection(….). Я могу сильно ошибаться, но, на мой взгляд, класс CString слишком «прост» для того, что бы необходима была «синхронизация неизвестно чего при помощи макро AFX_MANAGE_STATE.

3) Возможно, то, что ниже - просто моё брюзжание. Но, например, ЭТО (и подобное ему) просто раздражает:

Knowledge Base Articles BUG: Wincore.cpp Line 879 Assert When Using MFC Classes
Q192853
….


STDMETHODIMP CTest::TestMethod() { AFX_MANAGE_STATE(afxGetStaticModuleState()) CDatabase db; db.OpenEx("DSN=LocalServer;Database=pubs;UID=sa;PWD=;"); db.Close(); return S_OK; }

the assertion dialog appears.


Или ещё смешнее:


Visual C++ Concepts: Adding Functionality
Exported DLL Function Entry Points
….
….
AFX_MANAGE_STATE does not need to be put into every function in the DLL. For example, InitInstance can be called by the MFC code in the application without AFX_MANAGE_STATE because MFC automatically shifts the module state before InitInstance and then switches it back after InitInstance returns. The same is true for all message-map handlers. Regular DLLs actually have a special master window procedure that automatically switches the module state before routing any message.

Т.е., товарищи от мелкософт здесь и выше говорят, о том, что вообщем-то AFX_MANAGE_STATE не только не всегда следует использовать, но «просто так» - это ещё и вредно.

PS. Прошу подсказать мне, что же на самом деле происходит?
[C++] Это очень страшно. 27.09.03 18:09  
Автор: Tlo Статус: Незарегистрированный пользователь
<"чистая" ссылка>
(Ох, как вспомню как я бился с dll'ками, статически линкуемыми с MFC, страшно становиться).

Теперь немного по делу. Если ты принимаешь правила framework'а. то принимаешь их полностью. Поэтому, если тебе говорят, что переключать контексты надо во всех экспортируемых, то надо их переключать. А иначе придется делать заключения ореализацииклассов famework'а (так как ты, безусловно корректно, сделал для CString), что не всегда возможно, особенно, если хост и dll'ка собраны с разными версиями билдами MFC (не говоря уже о разных версиях).

Но это все баблинг (и наверное, void, все-таки не для тебя, а для менее искушенных). А что касается непосредственно AFX_MODULE_STATE, то если не ошибаюсь он хранит только инфу, необходимую для mfc'овых хуков - любые функции dll, создающие окна, например те, которые работают с mfc'овыми CAsyncSocket'ами (отгадайте почему :), должны переключить контекст -, и что-то там с DAO.

Здравый же смысл, действительно подсказывает, что тривиальные функции, неимеющие сношений с MFC не должны переключать контекст модулей (операция, прямо скажем сама по себе нетривиальная). Но опять-таки подчеркну свое imho (входящее в резонанс с mfc'овым ho) - если framework навязывает - надо выполнять. Это как с параметрами операций типа IUnknown - можно AddRef не делать - и так работать будет, но это уже отклонение от стандарта, и вся ответственность лежит уже на вас.

Ничего нового, конечно, но может поможет.
[C++] Это очень страшно. 28.09.03 01:41  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Cпасибо, Tlo, за мнение.

> Ничего нового, конечно, но может поможет.

Поможет ;)
Тем более, что это мнение человека, который, как видно, в этом направлении уже "копал".
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach