Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
3-32642
Rustik
2002-03-19 15:41
2002.04.11
Вылетает ошибка


1-32832
mike.dld
2002-03-28 17:45
2002.04.11
Это опять Я!


1-32727
ola
2002-03-29 06:04
2002.04.11
Help!!!! Помогите, уважаемые мастера....


1-32810
Евгений!
2002-03-31 21:29
2002.04.11
необходимо перехватить сообщения о изменении реестра и ФС


3-32646
KAA
2002-03-19 16:10
2002.04.11
Запрос для





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский