Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

круговерть с DLL [D5, Paradox]


Страницы:   1 2

der ©   (2002-03-06 12:48:00) 

всем привет!
Ситуация такая: есть прога, использующая datamodule (свойство active у всех таблиц включается в самом начале и не выключается до выхода из программы). Часть функций надо бы реализовать внешней DLL. Одна из них использует те же таблицы из datamodule. Как это все можно реализовать? Т.е. чтобы и в основной программе таблицы были активны, и в этой самой DLL можно было использовать фильтры, индексы и пр.. Это возможно?


deleon   (2002-03-21 14:05:00) [1]

1) Директива все-таки должна быть stdcall.
2) Все объекты, в том числе и компоненты, созданные в dll должны в ней-же и уничтожаться.
3) Компоненты в dll нельзя создавать через локальные переменные, только через глобальные, так как при завершении процедуры, очищается стек вместе с памятью распределенной через локальные переменные.
4) Все сделать реально, т.к. у меня заработало без всяких ошибок(таблицы и базы данных в dll, а формы отображения данных в приложении)
5) Удачи всем, кто пошел по этому пути!


deleon   (2002-03-15 08:50:00) [2]

Все заработало при загрузке и выгрузке библиоьеки одновременно с приложением и замене директивы stdcall на cdecl.


sniknik   (2002-03-14 16:02:00) [3]

Может быть надо попробовать а то как еще обьяснить компонент создеется и даже отрабатывает и тут же уничтожается сам по себе.


deleon   (2002-03-14 15:56:00) [4]

Я заметил, что если LoadLibrary сделать в начале загрузки программы, а в конце сделать выгрузку, то все почти работает. Похоже что память под компонент распределяется локально в dll и после вызова процедуры - очищается или что-то в этом роде!


deleon   (2002-03-14 15:42:00) [5]

Ок! Подожду и буду очень признателен!


deleon   (2002-03-14 15:41:00) [6]

Чувствую ничего из этой затеи не выйдет! Но почему при статической загрузке все работает, а при динамической нет ?!!!


sniknik   (2002-03-14 15:40:00) [7]

Там путаница с Hendl-ами поэтому и закрывается и ошибка вываливается. Подождеш до завтра? я дома разберусь а то работать тоже надо :) иногда.
у меня таблица откравается а гриде записи мелькают и тут же отключается. а ошибка при закрытии потому что пытается закрыть обьект которого уже нет.


deleon   (2002-03-14 15:19:00) [8]

Логика может и странная, но это плагин Database Workshop для доступа к Paradox-таблицам, поэтому другого пути нет! И у меня после открытия можно посмотреть все свойства таблицы, но грид упорно не показывает записи и при закрытии формы вываливается известная ошибка :(


sniknik   (2002-03-14 15:10:00) [9]

Теоретически уже работает, только почемуто при вызове из dll после открытия сразу таблицу закрывает :(. А вот логика странная я бы так не делал.


deleon   (2002-03-14 15:01:00) [10]

[sniknik] - ну как? есть какие-нибудь идеи ?


deleon   (2002-03-14 14:37:00) [11]

1) dbw_opendatabase - это тип (описан в DbwApi.pas)
2) function dbw_finddatabase - локальная в dll и не вызывается из вне.
3) Жаль что нет ICQ


sniknik   (2002-03-14 14:32:00) [12]

на первой функции не стоит в dll.
function dbw_finddatabase(pDesc: pdbw_dbdesc): TComponent; stdcall; <- (сдесь его не было!)
и с передачей параметров путаница например
в dll пишеш
function dbw_opendatabase(pDesc: pdbw_dbdesc; var iDb: TComponent): word; stdcall;
а в exe
OpenDb : dbw_opendatabase;
а надо так
OpenDb : function (pDesc: pdbw_dbdesc; var iDb: TComponent): word; stdcall;
и еще не обязательно имена прописывать так будет достаточно
exports
dbw_opendatabase,dbw_closedatabase,dbw_opentable,dbw_closetable;

это при первом рассмотрении может чтото еще щас отловлю све и вышлю как нибудь.

ICQ нет


deleon   (2002-03-14 14:30:00) [13]

[sniknik] - а ICQ у тебя есть ?


deleon   (2002-03-14 14:18:00) [14]

stdcall - везде стоит!
Пример уже выслал, посмотри если что поймешь ответь в этой теме :))) Спасибо!


sniknik   (2002-03-14 14:09:00) [15]

Письмо пришло а примера нет. Извини писмом ответить затруднительно у нас почта из сети не уходит (провайдер новый 1.5 месяца работает пока не отладили) повтори. и обрати внимание на ; stdcall; при описании процедур должно стоять и в dll и exe. (у меня были с этим смол проблемс)


deleon   (2002-03-14 13:58:00) [16]

[sniknik]Пример выслал - посмотри :)


deleon   (2002-03-14 13:54:00) [17]

Это все понятно...но у меня DbGrid в exe, а коннект создается в dll и передает в exe TDataSet, сейчас я тебе на мыло скину этот небольшой пример!


sniknik   (2002-03-14 13:48:00) [18]

Шутиш? Только динамическими пользуйся! гораздо удобнее (больше возможностей)

type
TCashProc = class(TComponent)
private
DllHandle: Thandle;
public
Proc: TCashProc;
DllName: String;
ConString: WideString;
DllInit: function (Own: TComponent; ConString: WideString): Boolean; stdcall;
DllClose: function: Boolean; stdcall;
GetInfo: function: PChar; stdcall; {}
GetConString: function (Handle: HWND; ConString: WideString): WideString; stdcall;
GetZNumber: function: PChar; stdcall; {}
ExistIn: function (Path: PChar): Boolean; stdcall;
CopyIn: function: PChar; stdcall;
DeleteIn: function (Path: PChar): Boolean; stdcall;
ExistOut: function (CashNo: Integer): Integer; stdcall;
CopyOut: function (CashNo: Integer; Path: PChar): PChar; stdcall;
DeleteOut: function: Boolean; stdcall;
constructor Create(Owner: TComponent; Dll: String; ConStr: WideString);
destructor Destroy; override;
end;

Const LoadOk: Boolean= True;

implementation

constructor TCashProc.Create(Owner: TComponent; Dll: String; ConStr: WideString);
begin
inherited Create(Owner);
DllHandle:= LoadLibrary(PChar(Dll));
if DllHandle >= 32 then begin
DllInit:= GetProcAddress(DllHandle, "DllInit");
if @DllInit = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция DllInit", mtError, [mbOk], 0);
LoadOk:= False;
end;
DllClose:= GetProcAddress(DllHandle, "DllClose");
if @DllClose = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция DllClose", mtError, [mbOk], 0);
LoadOk:= False;
end;
GetInfo:= GetProcAddress(DllHandle, "GetInfo");
if @GetInfo = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция GetInfo", mtError, [mbOk], 0);
LoadOk:= False;
end;
GetConString:= GetProcAddress(DllHandle, "GetConString");
if @GetConString = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция GetConString", mtError, [mbOk], 0);
LoadOk:= False;
end;
GetZNumber:= GetProcAddress(DllHandle, "GetZNumber");
if @GetZNumber = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция GetZNumber", mtError, [mbOk], 0);
LoadOk:= False;
end;
ExistIn:= GetProcAddress(DllHandle, "ExistIn");
if @ExistIn = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция ExistIn", mtError, [mbOk], 0);
LoadOk:= False;
end;
CopyIn:= GetProcAddress(DllHandle, "CopyIn");
if @CopyIn = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция CopyIn", mtError, [mbOk], 0);
LoadOk:= False;
end;
DeleteIn:= GetProcAddress(DllHandle, "DeleteIn");
if @DeleteIn = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция DeleteIn", mtError, [mbOk], 0);
LoadOk:= False;
end;
ExistOut:= GetProcAddress(DllHandle, "ExistOut");
if @ExistOut = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция ExistOut", mtError, [mbOk], 0);
LoadOk:= False;
end;
CopyOut:= GetProcAddress(DllHandle, "CopyOut");
if @CopyOut = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция CopyOut", mtError, [mbOk], 0);
LoadOk:= False;
end;
DeleteOut:= GetProcAddress(DllHandle, "DeleteOut");
if @DeleteOut = nil then begin
MessageDlg("Ошибка: в модуле не найдена функция DeleteOut", mtError, [mbOk], 0);
LoadOk:= False;
end;
ConString:= ConStr;
if LoadOk then LoadOk:= DllInit(Owner, ConString);
end else begin
MessageDlg("Ошибка: не могу найти "+Dll, mtError, [mbOk], 0);
LoadOk:= False;
end;
end;


deleon   (2002-03-14 13:35:00) [19]

А никто, выше-приведенный пример не пробовал сделать не статическим вызовом Dll, а динамическим?


Arhelon   (2002-03-06 14:21:00) [20]

Пишешь что обоих проэктах (и exe и dll)
uses
Sharemem,
....

и потом свободно передаешь в dll что угодно
типа

function gShow(ds:TDataSet): TForm; stdcall;
var f: TfGrid;
begin
f:=TfGrid.Create(Application);
f.ds:=ds;
f.s.DataSet:=ds;
f.g.Update;
f.Show;
result:=f;
end;

exports gShow;
енто модуль dll
а в модуле exe
function gShow(ds:TDataSet): TForm; stdcall; external "pDll.dll";
и далее
procedure TForm1.bDllClick(Sender: TObject);
begin
f:=gShow(ds);
end;
вот собственно и всё что могет помоч отцу русской демократии


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо