Форум: "Базы";
Текущий архив: 2002.04.11;
Скачать: [xml.tar.bz2];
Внизкруговерть с DLL Найти похожие ветки
← →
der (2002-03-06 12:48) [0]всем привет!
Ситуация такая: есть прога, использующая datamodule (свойство active у всех таблиц включается в самом начале и не выключается до выхода из программы). Часть функций надо бы реализовать внешней DLL. Одна из них использует те же таблицы из datamodule. Как это все можно реализовать? Т.е. чтобы и в основной программе таблицы были активны, и в этой самой DLL можно было использовать фильтры, индексы и пр.. Это возможно?
← →
deleon (2002-03-06 13:05) [1]Все это возможно, но это чревато кучей багов, хотя как напишешь :-)
← →
sniknik (2002-03-06 13:53) [2]Написать не проблема, просто передавай Table-s как параметры, можно даже класс DataModule передать. Все одно передаются только ссылки и в dll ты будеш работать с теми же таблицами что и в программе. Не понимаю только зачем? Но наверно нада. А касаемо багов не попробуеш не узнаеш, может именно у тебя их совсем не будет.
← →
Arhelon (2002-03-06 14:21) [3]Пишешь что обоих проэктах (и 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;
вот собственно и всё что могет помоч отцу русской демократии
← →
deleon (2002-03-14 13:35) [4]А никто, выше-приведенный пример не пробовал сделать не статическим вызовом Dll, а динамическим?
← →
sniknik (2002-03-14 13:48) [5]Шутиш? Только динамическими пользуйся! гораздо удобнее (больше возможностей)
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:54) [6]Это все понятно...но у меня DbGrid в exe, а коннект создается в dll и передает в exe TDataSet, сейчас я тебе на мыло скину этот небольшой пример!
← →
deleon (2002-03-14 13:58) [7][sniknik]Пример выслал - посмотри :)
← →
sniknik (2002-03-14 14:09) [8]Письмо пришло а примера нет. Извини писмом ответить затруднительно у нас почта из сети не уходит (провайдер новый 1.5 месяца работает пока не отладили) повтори. и обрати внимание на ; stdcall; при описании процедур должно стоять и в dll и exe. (у меня были с этим смол проблемс)
← →
deleon (2002-03-14 14:18) [9]stdcall - везде стоит!
Пример уже выслал, посмотри если что поймешь ответь в этой теме :))) Спасибо!
← →
deleon (2002-03-14 14:30) [10][sniknik] - а ICQ у тебя есть ?
← →
sniknik (2002-03-14 14:32) [11]на первой функции не стоит в 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:37) [12]1) dbw_opendatabase - это тип (описан в DbwApi.pas)
2) function dbw_finddatabase - локальная в dll и не вызывается из вне.
3) Жаль что нет ICQ
← →
deleon (2002-03-14 15:01) [13][sniknik] - ну как? есть какие-нибудь идеи ?
← →
sniknik (2002-03-14 15:10) [14]Теоретически уже работает, только почемуто при вызове из dll после открытия сразу таблицу закрывает :(. А вот логика странная я бы так не делал.
← →
deleon (2002-03-14 15:19) [15]Логика может и странная, но это плагин Database Workshop для доступа к Paradox-таблицам, поэтому другого пути нет! И у меня после открытия можно посмотреть все свойства таблицы, но грид упорно не показывает записи и при закрытии формы вываливается известная ошибка :(
← →
sniknik (2002-03-14 15:40) [16]Там путаница с Hendl-ами поэтому и закрывается и ошибка вываливается. Подождеш до завтра? я дома разберусь а то работать тоже надо :) иногда.
у меня таблица откравается а гриде записи мелькают и тут же отключается. а ошибка при закрытии потому что пытается закрыть обьект которого уже нет.
← →
deleon (2002-03-14 15:41) [17]Чувствую ничего из этой затеи не выйдет! Но почему при статической загрузке все работает, а при динамической нет ?!!!
← →
deleon (2002-03-14 15:42) [18]Ок! Подожду и буду очень признателен!
← →
deleon (2002-03-14 15:56) [19]Я заметил, что если LoadLibrary сделать в начале загрузки программы, а в конце сделать выгрузку, то все почти работает. Похоже что память под компонент распределяется локально в dll и после вызова процедуры - очищается или что-то в этом роде!
← →
sniknik (2002-03-14 16:02) [20]Может быть надо попробовать а то как еще обьяснить компонент создеется и даже отрабатывает и тут же уничтожается сам по себе.
← →
deleon (2002-03-15 08:50) [21]Все заработало при загрузке и выгрузке библиоьеки одновременно с приложением и замене директивы stdcall на cdecl.
← →
deleon (2002-03-21 14:05) [22]1) Директива все-таки должна быть stdcall.
2) Все объекты, в том числе и компоненты, созданные в dll должны в ней-же и уничтожаться.
3) Компоненты в dll нельзя создавать через локальные переменные, только через глобальные, так как при завершении процедуры, очищается стек вместе с памятью распределенной через локальные переменные.
4) Все сделать реально, т.к. у меня заработало без всяких ошибок(таблицы и базы данных в dll, а формы отображения данных в приложении)
5) Удачи всем, кто пошел по этому пути!
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.04.11;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c