Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите разобраться с DLL, Ай нид Хелп. 
:(
    Опции темы
AlexLogos
Дата 20.9.2010, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 23.4.2009

Репутация: нет
Всего: 1



Привет народ. Хочу разобраться с DLL. Уже который раз начинаю да все никак не закончу.
Есть у меня df.dll со следующим кодом

Код

library df;

uses
  ShareMem, SysUtils,
  Classes, SameRec in 'SameRec.pas', Forms;

{$R *.res}

procedure ShowSame1(num:Integer); stdcall;
var Same:TSameRecord;
begin
 Same:=TSameRecord.Create(Application);
 With Same do
  begin
   PnCaption.Caption:='найдено '+IntToStr(num)+' записей';
   ShowModal;
   FreeAndNil(Same);
  end;
end;

exports ShowSame1;
begin
end.


В программне я описываю ее
Код

var
  procedure ShowSame1(num:Integer); stdcall; external 'df.dll';


Вызываю по нажатию кнопки
Код

ShowSame1(5);


Появляеться окошко вызванной формы, но "надено 4776177 записей", по закрытии этой формы - AV и плюс ко всему когда закрываю основную прогу - форма исчезает, но процесс остается в памяти. Где я ошибся?
PM MAIL   Вверх
aleksh
Дата 22.9.2010, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 609
Регистрация: 8.7.2008

Репутация: 1
Всего: 13



а что будет если этот код использовать не в длл а в основном проекте? работает нормально?

покажи реализацию TSameRecord
PM MAIL   Вверх
AlexLogos
Дата 22.9.2010, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 23.4.2009

Репутация: нет
Всего: 1



Кода много, кое-где он однообразен, поэтому укорочу

Код

unit SameRec;

interface

uses
  ShareMem, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, ExtCtrls;

type
  TSameRecord = class(TForm)
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    PnCaption: TPanel;
    SpeedButton4: TSpeedButton;
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton4Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure SpeedButton3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  SameRecord: TSameRecord;

implementation

uses AddressFrame, AMTFrame, DocFrame, FilesFrame, ObjektFrame,
  OsobaFrame, RichFrame, SpezpovFrame, TelFrame;
var
  OsobaFr:TFrOsoba;
  DocFr:TFrDoc;
  NoteFr:TFrSpezpov;
  AmtFr:TFrAmt;
  FileFr:TFrFile;
  RichFr:TFrRich;
  ObjFr:TFrObject;
  TelFr:TFrTel;
  AdrFr:TFrAddress;
{$R *.dfm}

procedure TSameRecord.SpeedButton1Click(Sender: TObject);
begin
//ShowMessage(Self.Owner.ClassName);
 ModalF:=TForm.Create(Self);
 with ModalF do
  begin
   Height:=Round(Screen.Height*0.85);
   Width:=Round(Screen.Width*0.85);
   Top:=Round(Screen.Height*0.04);
   Left:=Round(Screen.Width*0.08);
   Caption:=Self.Owner.ClassName;
   Position:=poDesktopCenter;
  end;
if Self.Owner.ClassName='TFrOsoba' then
 begin
  OsobaFr:=TFrOsoba.Create(ModalF);
  with OsobaFr do
   begin
    Name:='FrOsoba';
    Parent:=ModalF;
    Visible:=True;
    Connect;//(TFrOsoba(Self.Owner).OSOsoba.Username,TFrOsoba(Self.Owner).OSOsoba.Password);
    ConTable:='Osoba';
    //TFrOsoba(Self.Owner).OQResult.SQL;
    OQResult.Active:=false;
    OQResult.SQL:=TFrOsoba(Self.Owner).OQResult.SQL;
    OQResult.ExecSQL;
    TFrOsoba(Self.Owner).OQResult.Active:=False;
    OQResult.Active:=True;
    ShowMain;
//    Tyda;
    RadioGroup1.Visible:=False;
    BBClear.Enabled:=False;
    BBSearch.Visible:=False;
    //BBBack.Visible:=False;
    ConType.Visible:=False;
    AddLink.Visible:=False;
    Memo1.Lines.Add(ConTable+' '+inttostr(ConId)+' '+ConnectionString);

    DBNav.Visible:=True;
    BBAddRec.Enabled:=False;
   end;
 end;
///.................................... 
ModalF.ShowModal;
Self.Close;
end;

procedure TSameRecord.SpeedButton2Click(Sender: TObject);
begin
Self.Close;
end;

procedure TSameRecord.SpeedButton3Click(Sender: TObject);
begin
if Self.Owner.ClassName='TFrOsoba' then  TFrOsoba(Self.Owner).SaveRecord;
if Self.Owner.ClassName='TFrFile' then  TFrFile(Self.Owner).SaveRecord;
Self.Close;
end;

procedure TSameRecord.SpeedButton4Click(Sender: TObject);
begin
if Self.Owner.ClassName='TFrOsoba' then
 with TFrOsoba(Self.Owner) do
  begin
   //Tyda;
   ShowMain;
   BBAddRec.Enabled:=False;
   //BBBack.Enabled:=True;
   DBNav.Visible:=True;
   ConnectConnections;
  { TFrKrumhk1.ShowMain;
   TFrPrukm1.ShowMain; }
  end;
////.......................................
Self.Close;
end;

end.



Может дело в том что TSameRecord ссылается на другие юниты?
PM MAIL   Вверх
aleksh
Дата 22.9.2010, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 609
Регистрация: 8.7.2008

Репутация: 1
Всего: 13



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

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

и еще - попробуй описать эту процедуру там же, откуда вызываешь и проверь как работает
PM MAIL   Вверх
AlexLogos
Дата 23.9.2010, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 23.4.2009

Репутация: нет
Всего: 1



Процедура которая описана в ДЛЛ взята из юнита форми, там она работает нормально. Я хотел несколько уменьшить код юнита и решил перенести несколько процедур в ДЛЛ. Начал из самой простой. 
Форма которая вызывает не уничтожается.
Я будрал FreeAndNil(Same); из ДЛЛ, и изменил тип передаваемых параметров так как ДЛЛ плохо работает со String.
Код

procedure ShowSame1(RecCou:integer;Parent:TComponent); stdcall;
var Same:TSameRecord;
begin
 Same:=TSameRecord.Create(Parent);
 With Same do
  begin
   PnCaption.Caption:='Найдено '+Inttostr(RecCou)+' записи(ей)';
   ShowModal;
  end;
end;

Теперь количество "Найдено ... записей" отображается праивльно, но по надатию на кнопки формы - получаю AV, да и после закрытия всех форм и программы - процес и дальше торчит в памяти... Какие особенности работы с ДЛЛ не учел я в работе?
PM MAIL   Вверх
cat512
Дата 23.9.2010, 09:57 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 438
Регистрация: 20.3.2007

Репутация: 2
Всего: 15



Если нет жёстких требований по использованию именно DLL в качестве контейнера кода, то лучше использовать BPL Об этом неоднократно писалось на этом форуме. Если же всё таки неюбходимо использование именно DLL то надо правильно (в DLL должны использоваться гл. объекты основного приложения) связывать объекты приложения с глобальными объектами VCL (Application, Session и т. д.), потому как в dll дублируется код VCL, уже существующий висполняемом модуле приложения (ехе). Ты понимаешь какой owner будет у твоего объекта при выполнении следующего кода???
Код

Same:=TSameRecord.Create(Application);

Если вызов TSameRecord  находится в dll то соответсвенно Application - ,будет тот который находится в DLL. Bpl лишены этого недостатка. Поэтому если используешь DLL то соответсвенно надо в функцию DLL передовать Application из основного приложения, либо использовать GetModuleHandle + GetProcAddress либо GetModuleHandle + FindHinstance (FindClassHinstance). Если используешь строки, дин. массивы, НЕ ЗАБУДЬ подключить SHAREMEM первым в файлы проектов основного приложения и DLL
И ещё один важный момент: операторы is, as опять же будут работать не коррекно по вышеописанной причине(дубль кода) Т.е. если передаёшь объектную ссылку из основного приложения
 а выполняешь сравнение по типу объекта в dll то оп. is вернёт ложный результат, так как сравнивает
в контексте RTTI DLL, а не основного приложения. Поэтому тут надо осторожно подходить к использованию объектов в DLL. Однако мне в одно время тоже приходилось использовать dll в качестве контейнера кода. Но у меня всё работало, потому как был вооружён. smile

Это сообщение отредактировал(а) cat512 - 23.9.2010, 19:55
PM MAIL   Вверх
AlexLogos
Дата 25.9.2010, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 23.4.2009

Репутация: нет
Всего: 1



Да действительно, я не в курсе был что в ДЛЛ свой Application. Темой ДЛЛ занялся недавно, да и в умной книге по Делфе таких тонкостей не было. По свободе опробую все что ты сказал.
PM MAIL   Вверх
bems
Дата 26.9.2010, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(AlexLogos @  20.9.2010,  09:57 Найти цитируемый пост)
procedure ShowSame1(num:Integer); stdcall;
var Same:TSameRecord;
begin
 Same:=TSameRecord.Create(Application);
 With Same do
  begin
   PnCaption.Caption:='найдено '+IntToStr(num)+' записей';
   ShowModal;
   FreeAndNil(Same);
  end;
end;
если это и все что делается с формой, то Application вообще не нужен. Делай так
Код

with TSameRecord.Create(nil) do
  try
    PnCaption.Caption:='найдено '+IntToStr(num)+' записей';
    ShowModal;
  finally
    Free
  end;


Добавлено через 1 минуту и 18 секунд
Или еще лучше: убрать Free, и в OnClose формы делай Action := caFree


--------------------
Обижено школьников: 8
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0768 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.