Форум: "Базы";
Текущий архив: 2007.09.02;
Скачать: [xml.tar.bz2];
Внизпередача процедуры в процедуре Найти похожие ветки
← →
alexey_mas © (2007-05-10 11:23) [0]Добрый день!
помогите определить правильно процедуру в дельфях.
Использую компоненты ZEOS для подключения к базе Postgres.
Пытаюсь получить все сообщения с сервера при помощи Notice Processing
procedure Tdog_transfer_form.NoticeTransfer(arg:Pointer;messages:PChar);cdecl;
begin
Memo1.lines.Add(messages);
end;
procedure Tdog_transfer_form.Button1Click(Sender: TObject);
var
Driver: IZPostgreSQLPlainDriver;
Conn: PZPostgreSQLConnect;
Arg: Pointer;
begin
Driver := (PasswordDlg.ZConnection1.DbcConnection as IZPostgreSQLConnection).GetPlainDriver;
Conn := (PasswordDlg.ZConnection1.DbcConnection as IZPostgreSQLConnection).GetConnectionHandle;
Driver.SetNoticeProcessor(conn,NoticeTransfer,arg); - вот здесь я указываю вторым параметром процедуру NoticeTransfer которая будет обрабатывать сообщения сервера
также здесь вылетает ошибка [Error] dog_transfer.pas(75): Incompatible types: "regular procedure and method pointer"
end;
в исходных кодах компонента процедура определена так:
procedure TZPostgreSQL7PlainDriver.SetNoticeProcessor(
Handle: PZPostgreSQLConnect; Proc:TZPostgreSQLNoticeProcessor;
Arg: Pointer);
begin
ZPlainPostgreSql7.PQsetNoticeProcessor(Handle, Proc, Arg);
end;
в свою очередь
TZPostgreSQLNoticeProcessor = procedure(arg: Pointer; message: PChar); cdecl;
Где я не так процедуру объявляю или вызываю?
Заранее спасибо.
← →
ЮЮ © (2007-05-10 11:35) [1]procedure Tdog_transfer_form.NoticeTransfer(arg:Pointer;messages:PChar);
это не процедура, а метод класса Tdog_transfer_form
regular procedure выглядела бы так:
procedure NoticeTransfer(arg:Pointer;messages:PChar);
← →
alexey_mas © (2007-05-10 11:40) [2]огромное спасибо. получилось
← →
alexey_mas © (2007-05-10 12:48) [3]ещё один нюанс возник.
procedure NoticeTransfer(arg:Pointer;messages:PChar);cdecl;
var
_tmp_str:string;
begin
ShowMessage(messages);
_tmp_str:=String(messages);
dog_transfer_form.Memo1.lines.Add(_tmp_str);
end;
В ShowMessage(messages) показывает строку.
Дебагером если смотреть то в переменной _tmp_str тоже показывает значение.
В мемо ничего не пишется
В чем может быть причина?
← →
Johnmen © (2007-05-10 13:02) [4]А ты хелп почитай про cdecl.
← →
alexey_mas © (2007-05-10 14:04) [5]почитал но не понял как применимо то что там написано к моему случаю.
при соглашении о вызовах cdecl параметры удаляются из стека при возврате из процедуры и читает параметры справа налево.
?
← →
Johnmen © (2007-05-10 14:10) [6]
> почитал но не понял как применимо то что там написано к моему случаю.
Если не понял, зачем написал?
← →
alexey_mas © (2007-05-10 15:22) [7]
> Johnmen ©
Как можно решить эту проблему? я так понимаю что ничего не добавляется потому что на момент выполнения метода Memo1.lines.Add парметр уже удален из стека.
← →
Johnmen © (2007-05-10 15:40) [8]
> Как можно решить эту проблему?
Убрать cdecl
> я так понимаю что ничего не добавляется потому что на момент
> выполнения метода Memo1.lines.Add парметр уже удален из
> стека.
Нет, ещё нет...
Чтобы это понять, надо знать, что такое строки в D и как организована работа с ними. Для этого надо читать документацию.
← →
alexey_mas © (2007-05-10 15:54) [9]
> > Как можно решить эту проблему?
>
> Убрать cdecl
убрать не могу так как используется С-ная dll
вот здесь 2-м параметром ожидается процедура с директивой cdecl.
Driver.SetNoticeProcessor(conn,NoticeTransfer,arg);
Если убираю ругается на Incompatible types: "Calling conventions differ"
← →
Johnmen © (2007-05-10 16:21) [10]Типа того
var
CallBackNoticeTransfer : TZPostgreSQLNoticeProcessor = nil;
...
CallBackNoticeTransfer:=@NoticeTransfer;
...
Driver.SetNoticeProcessor(conn,CallBackNoticeTransfer,arg);
← →
Виталий Панасенко © (2007-05-10 16:23) [11]А так ?
> procedure NoticeTransfer(arg:Pointer;messages:PChar);cdecl;
>
> var
> _tmp_str:string;
> begin
> ShowMessage(messages);
> _tmp_str:=String(messages);
> dog_transfer_form.Memo1.lines.Add(String(_tmp_str));
> end;
← →
Виталий Панасенко © (2007-05-10 16:27) [12]"гоню" после праздника..:-)
← →
alexey_mas © (2007-05-10 17:00) [13]
> Johnmen © (10.05.07 16:21) [10]
>
> Типа того
> var
> CallBackNoticeTransfer : TZPostgreSQLNoticeProcessor =
> nil;
> ...
> CallBackNoticeTransfer:=@NoticeTransfer;
> ...
> Driver.SetNoticeProcessor(conn,CallBackNoticeTransfer,arg);
>
сделал так.
1)в мемо ничего так и не попадает :(
2)messages всегда пусто теперь при вызове процедуры NoticeTransfer
:(
← →
Johnmen © (2007-05-10 17:08) [14]
> alexey_mas © (10.05.07 17:00) [13]
Приведи объявление TZPostgreSQLNoticeProcessor.
← →
alexey_mas © (2007-05-10 17:23) [15]TZPostgreSQLNoticeProcessor = procedure(arg: Pointer; message: PChar); cdecl;
← →
Johnmen © (2007-05-10 17:40) [16]Пробуй
var
s : string;
...
procedure NoticeTransfer(arg:Pointer;messages:PChar);cdecl;
...
s:=messages;
UniqueString(s);
dog_transfer_form.Memo1.lines.Add(s);
...
← →
alexey_mas © (2007-05-10 17:52) [17]аналогично в мемо не выводит.
через глобальную переменную вывожу- но так криво получается - после всех операций лог видим.
procedure NoticeTransfer(arg:Pointer;messages:PChar);cdecl;
var
_tmp_str:string;
begin
_tmp_str:=Trim(String(messages));
UniqueString(_tmp_str);
_global_str:=_global_str+#13+#10+_tmp_str;
dog_transfer_form.Memo1.lines.Add("test"+_tmp_str);
end;
← →
Johnmen © (2007-05-10 17:57) [18]
> после всех операций лог видим.
Это о чём?
← →
alexey_mas © (2007-05-10 18:08) [19]messages:PChar - это сообщения от сервера Postgres (Notice and warning messages generated by the server)
идея состоит в том что во время выполнения удаленных процедур все сообщения сразу же транслируются в мемо.
Пока получилось используя глобальную переменную объявленную в модуле _global_str выводить сообщения после окончания операций с сервером.
Привожу весь код модуля
unit dog_transfer;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, DB, ZAbstractRODataset, ZAbstractDataset,
ZDataset, ZConnection,ZPlainPostgreSql8,ZPlainPostgreSqlDriver,ZDbcPostgreSql;
type
Tdog_transfer_form = class(TForm)
Memo1: TMemo;
Panel1: TPanel;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
ZQuery1: TZQuery;
ZQuery2: TZQuery;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
dog_transfer_form: Tdog_transfer_form;
_global_str:string;
implementation
uses password;
{$R *.dfm}
procedure NoticeTransfer(arg:Pointer;messages:PChar);cdecl;
var
_tmp_str:string;
text_file:textfile;
begin
_tmp_str:=Trim(String(messages));
if ((_tmp_str<>"") and (_tmp_str<>"NOTICE:")) then begin
if pos("BASE64~|~",_tmp_str)=0 then _global_str:=_global_str+#13+#10+_tmp_str;
UniqueString(_tmp_str);
dog_transfer_form.Memo1.lines.Add("test"+_tmp_str);
end;
end;
procedure Tdog_transfer_form.Button1Click(Sender: TObject);
var
Driver: IZPostgreSQLPlainDriver;
Conn: PZPostgreSQLConnect;
Arg: Pointer;
idtransact:integer;
id_shema:string;
CallBackNoticeTransfer:TZPostgreSQLNoticeProcessor;
begin
id_shema:="9";
Driver := (PasswordDlg.ZConnection1.DbcConnection as IZPostgreSQLConnection).GetPlainDriver;
Conn := (PasswordDlg.ZConnection1.DbcConnection as IZPostgreSQLConnection).GetConnectionHandle;
PasswordDlg.ZConnection1.StartTransaction;
arg:=Tdog_transfer_form.MethodAddress(Memo1.Text);
try
idtransact:=Driver.GetBackendPID(conn);
Memo1.lines.Add("Получен PID = "+intToStr(idtransact));
// CallBackNoticeTransfer:=@NoticeTransfer;
// Driver.SetNoticeProcessor(conn,CallBackNoticeTransfer,arg);
Driver.SetNoticeProcessor(conn,NoticeTransfer,arg);
ZQuery1.Close;
ZQuery1.SQL.Clear;
ZQuery1.SQL.Text:="select * from dog_inittransfer(:idtrans)";
ZQuery1.ParamByName("idtrans").AsInteger:=idtransact;
ZQuery1.ExecSQL;
ZQuery2.Close;
ZQuery2.SQL.Clear;
ZQuery2.SQL.Text:="insert into init_transfer(idobj,paramcode,data) values (cast(:idobj as integer),cast(:paramcode as varchar),cast(:data as varchar))";
ZQuery2.ParamByName("idobj").AsInteger:=idtransact;
ZQuery2.ParamByName("paramcode").AsString:="DATA_ID";
ZQuery2.ParamByName("data").AsString:=id_shema;
ZQuery2.ExecSQL;
ZQuery2.Close;
ZQuery2.SQL.Clear;
ZQuery2.SQL.Text:="select * from dog_transfer(cast(:piddog as integer),cast(:plpwd as varchar),cast(:puser as text),cast(:ppwd as text),cast(:ptypeoper as varchar),cast(:pidobj as text),cast(:pidtr as integer) )";
ZQuery2.ParamByName("piddog").AsInteger:=idtransact;
ZQuery2.ParamByName("plpwd").AsString:=Driver.GetPassword(conn);
ZQuery2.ParamByName("puser").AsString:=Trim(Edit1.Text);
ZQuery2.ParamByName("ppwd").AsString:=Trim(Edit2.Text);
ZQuery2.ParamByName("ptypeoper").AsString:="DATA";
ZQuery2.ParamByName("pidobj").AsString:="";
ZQuery2.ParamByName("pidtr").AsInteger:=idtransact;
ZQuery2.ExecSQL;
Memo1.lines.Add("Получены данные от dog_transfer");
ZQuery2.Close;
ZQuery2.SQL.Clear;
ZQuery2.SQL.Text:="select * from dog_recive(cast(:piddog as integer),cast(:plpwd as varchar),cast(:pidtr as integer) )";
ZQuery2.ParamByName("piddog").AsInteger:=idtransact;
ZQuery2.ParamByName("plpwd").AsString:=Driver.GetPassword(conn);
ZQuery2.ParamByName("pidtr").AsInteger:=idtransact;
ZQuery2.ExecSQL;
Memo1.lines.Add("Получены данные от dog_receive");
PasswordDlg.ZConnection1.Commit;
except
Memo1.lines.Add("Во время транзакции получена ошибка");
PasswordDlg.ZConnection1.Rollback;
end;
Memo1.Lines.Add(_global_str);
end;
end.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2007.09.02;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.043 c