Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

DLL библиотеки

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Чт Июл 19 2007 18:41    Заголовок сообщения: DLL библиотеки Ответить с цитатой

Всем привет. Стыдно конешно не знать, но весётаки: Где dll библиотеки выделяют память под объекты?
Если всётаки в куче главного процесса то у меня такая проблема - из одной дллки в другую передаю указатель на TADODataSet и всё в принципе в порядке но когда обращаешься к нему вот такой вот банальной строчкой
str:=TADODataSet(DataSet^).Fields[1].AsString;
после закрытия формы в коде к которой это написано вылазит косяк о том что инструкция по адрему блаблабла обратилась не к тому куску памяти. Не могу понять в чём дело уже не первый день. Люди помогите!!!!
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Mytilus Galloprovincialis



Зарегистрирован: 30.08.2005
Сообщения: 358
Откуда: откуда все люди родятся

СообщениеДобавлено: Пт Июл 20 2007 03:47    Заголовок сообщения: Ответить с цитатой

Во-первых, все зависит от того, как ты пользуешься dll. Во-вторых, каждое приложение получает часть памяти и использует его и только его. Адрес объекта - это не порядковый номер байта всей-всей памяти, но только ее фрагмента, выделенного приложению. Две разные проги, обращаясь по одному и тому же адресу, попадают в разные места памяти. Программист не может читать и писать в память другого приложения. (Может, конечно... Но таких программистов называют "хакерами" Wink). Так что придется обойти эту проблему и найти альтернативный путь решения.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Пт Июл 20 2007 05:24    Заголовок сообщения: Ответить с цитатой

Что значит выражение "как ты пользуешься dll"? Подразумевается явное и неявное связавание? Я использую явное по именам экспортируемых процедур. И я так и не понял из ответа у dll и приложения общяя память или нет?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Mytilus Galloprovincialis



Зарегистрирован: 30.08.2005
Сообщения: 358
Откуда: откуда все люди родятся

СообщениеДобавлено: Сб Июл 21 2007 01:20    Заголовок сообщения: Ответить с цитатой

Нет, не общая. Пользуйся мессагами или COM.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Вт Июл 24 2007 17:47    Заголовок сообщения: Ответить с цитатой

Дык как раз com я и пользую. Понимаешь в чём фишка из дллки я могу передать в прогу всё что угодно а вот именно набор данных не могу, обращение к ниму вызывает ошибку и что больше всего запутывает ошибка возникает не всегда но в процентах в 90 случаев
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Mytilus Galloprovincialis



Зарегистрирован: 30.08.2005
Сообщения: 358
Откуда: откуда все люди родятся

СообщениеДобавлено: Ср Июл 25 2007 00:04    Заголовок сообщения: Ответить с цитатой

Если я правильно понял проблему, то выход из нее может быть таким. Создаешь и реализуешь в ДЛЛ класс или структуру и экспортируешь в приложение. И если все правильно сделано, должно работать на 100 процентов.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Ср Июл 25 2007 17:11    Заголовок сообщения: Ответить с цитатой

Ты правельно понял, есть com интерфейс у проги, процедуру этого интерфейса вызывает дллка а параметр процедуры это указатель типа ^TADODataSet с датасетом по этому указателю ты можешь делать всё что угодно пока не обращаешься к свойству fields, само обращение проходит нормально но дллка после тагоко обращения программы к её датасету закрывается с ошибкой. Как ты правельно заметил должно работать на 100% но получается 100%-%(fields)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Mytilus Galloprovincialis



Зарегистрирован: 30.08.2005
Сообщения: 358
Откуда: откуда все люди родятся

СообщениеДобавлено: Чт Июл 26 2007 00:01    Заголовок сообщения: Ответить с цитатой

А отловить и "задавить" исключение нельзя? И обязательно ли использовать DLL?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
критикан



Зарегистрирован: 18.02.2005
Сообщения: 247

СообщениеДобавлено: Чт Июл 26 2007 10:07    Заголовок сообщения: зачем нужен com, если есть ip/port? Ответить с цитатой

Hastur писал(а):
Дык как раз com я и пользую. Понимаешь в чём фишка из дллки я могу передать в прогу всё что угодно а вот именно набор данных не могу, обращение к ниму вызывает ошибку и что больше всего запутывает ошибка возникает не всегда но в процентах в 90 случаев

технология com была разработана на принципах технологии ole, которая предполагала доступ к функциям/процедурам dll-ки только через механизм экспортируемых функций. никаких прямых доступов к неэкспортируемым функциям/процедурам и к переменным dll-ки нет. именно поэтому обращение к памяти, закреплённой за dll-кой, вызывает ошибку обращения к запрещённой области памяти. и именно поэтому в технологии com предумотрена специальная функция QueryInerface(), которая возвращает указатель на запрошенный интерфейс. этот указатель является не адресом в памяти, которая принадлежит dll-ке, а адресом метода доступа к функциям/процедурам и к переменным dll-ки.

причина такого способа доступа в том, что технология com рассчитана на применение в пределах не одной машины, а сети, поэтому dll-ка -- точнее, исполняемый модуль -- может находиться вообще на другой машине, правда тогда он по очевидным причинам будет скомпилирован не в виде dll-ки, а виде exe-шника. соответственно доступ к набору данных может быть осуществлён только через специальный метод, а не напрямую

вывод: в dll-ке дожна быть специальная функция/процедура доступа к отдельным значениям набора данных
------------------
зачем нужен com, если есть ip/port?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Чт Июл 26 2007 18:07    Заголовок сообщения: Ответить с цитатой

критикан писал(а):
никаких прямых доступов к неэкспортируемым функциям/процедурам и к переменным dll-ки нет. именно поэтому обращение к памяти, закреплённой за dll-кой, вызывает ошибку обращения к запрещённой области памяти. и именно поэтому в технологии com предумотрена специальная функция QueryInerface(), которая возвращает указатель на запрошенный интерфейс. этот указатель является не адресом в памяти, которая принадлежит dll-ке, а адресом метода доступа к функциям/процедурам и к переменным dll-ки.
------------------
зачем нужен com, если есть ip/port?


Видимо я что-то упустил при изучение com. Интерфес что, может пренадлежать не только классу, а например дллки?

А с косяком я всётаки разобрался(частично), я перед тем как передовать dataset из дллки вызывал его метод DisableControls который как-то негативно влияет на текущий набор данных(почему и как я не понял) без этого метода всё отлично работает.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
критикан



Зарегистрирован: 18.02.2005
Сообщения: 247

СообщениеДобавлено: Чт Июл 26 2007 18:57    Заголовок сообщения: dde-ole-com-dcom'ские нары против ip/port'ового гамака? ха! Ответить с цитатой

Hastur писал(а):
Видимо я что-то упустил при изучение com. Интерфес что, может принадлежать не только классу, а например дллки?

некорректно говорить "интерфейс может принадлежать классу". интерфейс сам по себе является классом, причём он должен быть наследником класса IUnknown. кстати, так как класс IUnknown имеет (публичный) метод QueryInerface(), то и все другие интерфейсы имеют этот метод, и именно поэтому у всех других интерфейсов можно запросить, существуют ли они.

Hastur писал(а):
А с косяком я всётаки разобрался(частично), я перед тем как передовать dataset из дллки вызывал его метод DisableControls который как-то негативно влияет на текущий набор данных(почему и как я не понял) без этого метода всё отлично работает.

не рискую критиковать выбранный способ лечения, тем не менее считаю, что способ лечения не будет правильным, если неясно, что именно он лечит. DisableControls, скорее всего, должен быть ни при чём. Но повторяю, в данном случае не могу критиковать правильность выбранного решения. Я бы поискал причину в другом.
-------------------------------------------
"не умножай сущностей без надобности", -- сказал юникс, качаясь в гамаке, сделанному из паутины ip/port'ов, микрософту про его нары, сделанные из поленьев dde-ole-com-dcom
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Ср Авг 01 2007 18:44    Заголовок сообщения: Ответить с цитатой

Ну не будем придераца к формулировкам. Но ты всётаки ответь, когда класс наследует интерфейс то указатель на него можно получить строчкой вид myObject.GetInterface(бла,бла) а в случае с dll как оно?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
igor406



Зарегистрирован: 27.06.2007
Сообщения: 11

СообщениеДобавлено: Чт Авг 02 2007 08:32    Заголовок сообщения: Ответить с цитатой

Цитата:
некорректно говорить "интерфейс может принадлежать классу". интерфейс сам по себе является классом

Опять же некорректно. Класс может реализовывать интрефейс, но интерфйес сам по себе хоть и похож на абстрактный клас, тем не менее таковым не является. Модель интерфейса в корне отлична от модели класса. Класс - декларация типов объектов. Интерфейс - декларация некоторой функциональности.

Цитата:
Где dll библиотеки выделяют память под объекты?

Некорректный вопрос. Dll сама никакой памяти не выделяет. Виндятина грузит код длл в адресное пространство расшариваемое через специальный механизм для тех процессов, которые используют эту ДЛЛ (это делается для экономии памяти). В то же время для данных, используемых в ДЛЛ отводится место в адрессном пространстве процесса. Это справедливо для энтишного ядра, но не для 9Х. Поэтому в ХР, к примеру невозможно НЕПОСРЕДСТВЕННО через механизм длл организовать межпроцессный обмен данными, а вот в 95-м можно было.

Цитата:
всё в принципе в порядке но когда обращаешься к нему вот такой вот банальной строчкой
str:=TADODataSet(DataSet^).Fields[1].AsString;
после закрытия формы в коде к которой это написано вылазит косяк о том что инструкция по адрему блаблабла обратилась не к тому куску памяти.

Дело в том, что в делфях такие глобалные объекты как Application и Screen в каждой ДЛЛ свои и многие компоненты завязанные на них (та же хрень получится и с TBitmap) будут некорректно себя вести, будучи переданные по ссылке в основной код программы. Поэтому чтоб с ними работать необходимо их "отвязать" (о чём собсно и было сказано в последнем посте):
Цитата:
А с косяком я всётаки разобрался(частично), я перед тем как передовать dataset из дллки вызывал его метод DisableControls который как-то негативно влияет на текущий набор данных


Цитата:
Дык как раз com я и пользую... Подразумевается явное и неявное связавание? Я использую явное по именам экспортируемых процедур
Чё-то ты противоречишь себе, как следует из написанного тобой ранее, ты просто используешь импорт процедур из ДЛЛ. При чём тут ком? И вообще (это касается многих последующих постов) ком и длл - совершенно разные вещи. Да, ком-объект может в качестве своей резиденции иметь ДЛЛ (в этом случае он называется встроенным ком-сервером, в отличие от случая, когда он реализован в экзешнике). Если хотите поговорить про ком-технологию, то это тема для отдельного разговора
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Чт Авг 02 2007 17:20    Заголовок сообщения: Ответить с цитатой

Цитата:
Дело в том, что в делфях такие глобалные объекты как Application и Screen


Знаю об этом поэтому при ирициализации dll заменяю её априкейшен и скрин на те которые используются в главной программе. Но это как оказалось приблемы с компонентами бд не решает, возможно есть ещё какой-нибудь глобальный объект?

Цитата:
Виндятина грузит код длл в адресное пространство расшариваемое через специальный механизм для тех процессов, которые используют эту ДЛЛ (это делается для экономии памяти). В то же время для данных, используемых в ДЛЛ отводится место в адрессном пространстве процесса. Это справедливо для энтишного ядра, но не для 9Х. Поэтому в ХР, к примеру невозможно НЕПОСРЕДСТВЕННО через механизм длл организовать межпроцессный обмен данными, а вот в 95-м можно было.


Спасибо за информацию. Не подскажешь мануальчик на эту тему?

Цитата:
Чё-то ты противоречишь себе


Архитектура такова. В дллках лежат классы форм, а классы соответственно потдерживают(или реализуют функциональность объявленную в интерфейсе Very Happy уж не знаю как корректней) некоторые интерфейсы, посредствам которых и общаются формы.
Сей опломб архитектуры прошу не ругать, очень много читал по поводу организации подобных архитектур о всех их плюсах и минусах.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
igor406



Зарегистрирован: 27.06.2007
Сообщения: 11

СообщениеДобавлено: Пт Авг 03 2007 06:41    Заголовок сообщения: Ответить с цитатой

Цитата:
Знаю об этом поэтому при ирициализации dll заменяю её априкейшен и скрин на те которые используются в главной программе. ... возможно есть ещё какой-нибудь глобальный объект

Правильно. Много чего ещё есть, и в каждом отдельном случае надо копать до самого дна.

Цитата:
Не подскажешь мануальчик на эту тему

Лично я не знаю какого-то одного труда (достаточно адекватного), посвящённого конкретно этой тематике. Приходилось собирать всё по крупицам, читая литературу под авторством Рихтера, Русиновича и пр., MSDN, да и просто делфовый хелп.

Цитата:
Архитектура такова ...

Лично я давно уже использую следующий подход: ДЛЛ экспортирует единственную функцию, возвращающую указатель на объект-концентратор реализующий некий интерфейс (т.е. можно сказать, что функция возвращает указатель на интерфейс), позволяющий получить доступ к функционалу (реализованному соответственно через некоторую ООО модель). Именно интерфейсы позволяют организовать достаточно эффективное применение ООО-программирования в контексте ДЛЛ. Ещё один плюс интерфейсов в том, что они позволяют организовать подобие множественного наследования, а также подобие автоматической сборки мусора - короче, если подружиться с интерфейсами, то окажется, что это вещь жизненно необходимая.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Пт Авг 03 2007 16:56    Заголовок сообщения: Ответить с цитатой

Цитата:
ДЛЛ экспортирует единственную функцию, возвращающую указатель на объект-концентратор реализующий некий интерфейс


Спасибо за информацию, надо будет попробовать
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Ср Авг 29 2007 08:55    Заголовок сообщения: Ответить с цитатой

Цитата:
Да, ком-объект может в качестве своей резиденции иметь ДЛЛ (в этом случае он называется встроенным ком-сервером, в отличие от случая, когда он реализован в экзешнике)


Ты сам пробовал написать такой ком-сервер? Я чёто не нашол ни одного мануала по этой теме, везде рассматривается вариант с формой в длл и её интерфейсом

Цитата:
Лично я давно уже использую следующий подход: ДЛЛ экспортирует единственную функцию, возвращающую указатель на объект-концентратор реализующий некий интерфейс


Попробовал запинать свой класс в длл и получить от него интерфейс вот код

h:=LoadLibrary(PChar(path));
addr:=GetProcAddress(h,PChar('GetObject'));
obj:=addr(App);
obj.GetInterface(IUnitsInformation,intr);

интерфей получил, отлично с ним работаю app это апликейшен
приложения

addr1:=GetProcAddress(h,PChar('CloseModule'));
addr1;
CurInfo:=Info;
FreeLibrary(h);

При закрытие длл вылетает ошибка

---------------------------
Debugger Exception Notification
---------------------------
Project Monopolia.exe raised exception class EAccessViolation with message 'Access violation at address 004046DE in module 'Monopolia.exe'. Read of address 02B1F068'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------

Ты с таким не сталкивался?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Mytilus Galloprovincialis



Зарегистрирован: 30.08.2005
Сообщения: 358
Откуда: откуда все люди родятся

СообщениеДобавлено: Вс Сен 02 2007 06:44    Заголовок сообщения: Ответить с цитатой

Я вообще не сторонник пихать свои классы в DLL. После моей упорной борьбы с DLL, я понял, что библиотеки очень ненадежны при работе с ссылками и указателями. Чтобы все работало, что называется, "на ура", надо влить в свою прогу пригоршню геморроя и пару-тройку бессонных дней своей жизни. Поэтому пишу несложные межпрограммные классы отдельными модулями, а массивным классам ищу альтернативы.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Hastur



Зарегистрирован: 14.06.2007
Сообщения: 24

СообщениеДобавлено: Ср Сен 05 2007 17:42    Заголовок сообщения: Ответить с цитатой

Если кому интересно выше указанный косяк возникал в из-из того что из dll я передавал функцией строку(string). Как оказалось предавать делфя может только указатель на нуль-терменированные строки(PСhar и ему подобные) или массивы символов. Видимо такое ограничение вызвано тем что работа с dll ведётся исключительно винапишными функциями а тип string и ему подобные не имеют аналога в винапи, чего не скажешь о PChar
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
igor406



Зарегистрирован: 27.06.2007
Сообщения: 11

СообщениеДобавлено: Пн Сен 10 2007 15:11    Заголовок сообщения: Ответить с цитатой

Hastur
Цитата:
Если кому интересно выше указанный косяк возникал ...

если будешь при интеграции ДЛЛ-ки использовать не указатели на классы, а указатели на интерфейсы, то в методах интерфейсов сможешь использовать и тип string;

Цитата:
Ты сам пробовал написать такой ком-сервер?

Постоянно использую подобные вещи. Могу порекомендовать по этой теме Эрик Хармон. Разработка COM-приложений в среде Delphi

Mytilus Galloprovincialis
Цитата:
Я вообще не сторонник пихать свои классы в DLL ...

Тогда уделом вашим будут маленькие простенькие программки...
Большая серъёзная система невозможна без этого, без применения интерфейсов (я про языковую конструкцию, а не про интерфесы вообще), оверрайда виртуальных методов и т.д. и т.п.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...