Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.04.2013, 07:34   #1
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию где хранятся данные при работе с dll ?

вопрос кажется глупым, поскольку очевидно, что
все, что создано функциями в dll, там же и лежит,
а все что создано в программе - лежит в программе.

я написал простенькую dll-ку, которая загружает jpg.
вот ее код:

Код:
library LoadJPEG;

uses
  SysUtils, Classes, Graphics, JPEG;

procedure LoadJPGFromFile(B:TBitmap; Path:PChar);  stdcall;
var
J:TJPEGImage;
begin
  if FileExists(Path) then
  begin
  J:=TJPEGImage.Create; 
  J.LoadFromFile(Path);
  B.Width:=J.Width;
  B.Height:=J.Height;
  B.Canvas.Draw(0,0,J);
  J.Free;  
  end;
end;

exports LoadJPGFromFile;

begin
end.
программе использую динамическую загрузку dll, здесь проблем нет,
все загружается, процедура находится, выполняется как надо, код приводить не буду...

в итоге имею такой алгоритм:

создаем TBitmap // в программе
загружаем dll
запускаем процедуру из dll // при этом изменяется битмап, созданный в программе
выгружаем dll
рисуем битмап на канвасе формы

при этом возникает Access Violation,
но если dll не выгружать, то все работает...

складывается такое впечатление, что битмап был в dll создан,
а потом вместе с ней и выгрузился...

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

откройте мне глаза на мир, с чем связано такое поведение?
Заранее спасибо! =)
xrob вне форума Ответить с цитированием
Старый 18.04.2013, 08:06   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
рисуем битмап на канвасе формы
Ты в ДЛЛ передаешь канву формы???
Тогда не лучше ли вместо B:TBitmap передавать B:TCanvas?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.04.2013, 08:44   #3
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

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

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

Последний раз редактировалось xrob; 18.04.2013 в 08:51.
xrob вне форума Ответить с цитированием
Старый 18.04.2013, 10:08   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Ну попробуй так: LoadJPGFromFile(Path:PChar;var B:TBitmap);
Я не копенгаген в плагинах, но вдруг поможет.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.04.2013, 10:27   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Передавать в dll не экземпляр класса TBitmap, а его Handle
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 18.04.2013, 12:33   #6
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

Stilet, тоже была идея с var, но не прокатила...
впрочем я этому не удивляюсь, поскольку var в этом случае роли не играет.
B - это и так указатель.
ведь как мы создаем битмап?

B:=TBitmap.Create; конструктор Create создает нечто, где-то в памяти,
и возвращает ссылку на это нечто - т.е. по сути указатель.

мы можем, например сделать так: C:=B;
что по-вашему произойдет?
если бы B и C были record, например, то одна запись скопировалась бы в другую
и стало бы две одинаковых записи.
и вот в этом случае var играл бы роль - процедура работала бы именно с той записью,
которую ей передали, а не создала бы себе такую же.

а вот если B и C - ссылки на созданные с помощью Create объекты,
то при C:=B; сам объект так и останется лежать, где лежал, но будет просто две
одинаковые ссылки на один и тот же объект...
поэтому в procedure(B:TBitmap); B по определению передается как var.


Аватар, с handle не пробовал, но чем B не хендл?
xrob вне форума Ответить с цитированием
Старый 18.04.2013, 13:03   #7
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
создаем TBitmap // в программе
загружаем dll
запускаем процедуру из dll // при этом изменяется битмап, созданный в программе
выгружаем dll
рисуем битмап на канвасе формы

при этом возникает Access Violation,
но если dll не выгружать, то все работает...
DLL тоже самое что и exe, только не имеет точки старта.
DLL имеет собственное адресное пространство, выгрузив DLL вы убиваете все что связано с этой DLL. Лбые объекты созданные в коде DLL живут в АП этой DLL а не где-то ещё.
Адрес B с которым вы раотаете после обработки DLL - живет в стэке АП от dll(вроде бы..).
Попробуйте передавать handle, как уже сказали.

P.S.
А надо ли вообще создавать DLL ради 1 метода и иметь этот геморой?

Последний раз редактировалось Человек_Борща; 18.04.2013 в 13:06.
Человек_Борща вне форума Ответить с цитированием
Старый 18.04.2013, 13:25   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Че нибудь в таком духе, при обращении передавать Bitmap.Handle
Код:
procedure LoadJPGFromFile(HBitmap: HBITMAP; Path:PChar);  stdcall;
var J:TJPEGImage;
    B: TBitmap;
begin
  if FileExists(Path) then
  begin
    J:=TJPEGImage.Create;
    J.LoadFromFile(Path);
    B:=TBitmap.Create;
    B.Handle:=HBitmap;
    B.Assign(j);
    B.ReleaseHandle;
    B.Free;
    J.Free;
  end;
end;
ADD наличие проверки на существование файла не исключает проблем при его загрузке, поэтому наличие try...except обязательно
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 18.04.2013 в 13:32.
Аватар вне форума Ответить с цитированием
Старый 18.04.2013, 22:18   #9
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

Человек_Борща, ради того, чтобы навсегда забыть про delphi7, я бы пошел и не на такое.

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

я работаю в Delphi 10 Lite.
Она урезана на процентов 90, я полагаю, в отличие от delphi7 в плане компонентов, НО!
1. Процедуры сворачиваются.
2. Запущенный процесс в случае зависания можно прервать из среды в 99% случаев
3. Окна среды не проваливаются сквозь пальцы
4. Дизайн формы и код юнита располагаются в ОДНОМ окне, и переключаются с помощью вкладок
5. ключевые слова begin читаются гораздо лучше, чем end; в черном тексте.

проблема в том, что в д10 нет JPEG.dcu...
а мне без вариантов нужна прога, которая может загружать jpeg.
раньше я полагал, что весь проект разработаю на д10, а потом скомпилирую его на д7 - язык то ведь один и тот же.
что сказать? я был наивен. Несколько дней переноса проекта на д7 - вот истинный геморрой.
и что в результате? приложение, работающее менее стабильно, чем написанное на д7.

Так что, уважаемый Человек_Борща, написать dll с единственным методом,
ради того, чтобы забыть про д7 - это не геморрой, а вершина моего блаженства в этом году.

Тем более, что единственная проблема, возникшая с dll - описана в этой теме.
И по большому счету это не проблема, я просто выгружать ее не буду
Если только в OnСlose формы, хотя он, ведь не наступит, если удалить процесс в диспетчере задач?

Аватар, да я понял вас, попробую с handle.

Кстати, по поводу загрузки/разгрузки dll - это ведь не секундное дело?
И если прога, например, постоянно загружает jpg, то надо ли каждый раз загружать/выгружать библиотеку?
мне кажется нет...

Кстати, Аватар, B.Assign(j); - говорит что нельзя назначить TJPEGImage в TBitmap...
хотя меня это не удивляет - библиотека написана на д7, а TBitmap из д10...

Последний раз редактировалось xrob; 18.04.2013 в 22:26.
xrob вне форума Ответить с цитированием
Старый 18.04.2013, 22:34   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

там проблемы с менагером памяти, ShareMem как бы была для этого.
суть в том что у длл свой менагер памяти, который и умирает вместе с ней(убивая все данные).
так же у вас будет проблема если вы захотите уничтожить свой джипег.

вместо урезанных дельфей, скачайте нормальную.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
где хранятся настройки принтэра? VAnj2607 Помощь студентам 6 07.05.2011 11:07
Ошибка при работе с DLL _-Re@l-_ Общие вопросы Delphi 1 28.08.2010 20:55
Где хранятся настройки редактора VBA? viter.alex Microsoft Office Word 5 04.10.2009 16:34
Где хранятся настройки Opera и MS Outlook? Cannibal Windows 1 27.12.2008 17:52
Где хранятся драйвера? (windows vista) Hallo Свободное общение 10 05.09.2007 07:47