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

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

КАК принять данные из DLL ?


SerGH ©   (2006-05-06 13:00:00) 

Здравствуйте,уважаемые Мастера,здравствуйте,уважаемый Сергей М.Не могли бы Вы помочь.Есть две программки,назначение одной-отправка данных,назначение второй -прием данных.Связь м/у ними осуществляет DLL,состоящая из клиетской и серверной частей.Как передать данные из DLL в программу-приемник?


Slym   (2006-05-10 05:49:00) [1]

SerGH ©   (06.05.06 15:07) [9]
универсальные данные-данные любого типа:integer,string и т.п.

WinSock это умеет :)

Ряд неясеностей:
1. Будут это простые типы данных или сложные (record, array)?
2. Принимающая сторона знает что принимает или заранее ей не известен тип/размер принимаемых данных. (принял 4 байта стринга, а на самом деле это интегер :(

Оба упираются в отсутствие "протокола" обмена
Если типы данных сложные бери за основу XML, там и имя переменной и тип и прочие атрибуты.
если простой тип данных то протокол можно упростить.


Сергей М.   (2006-05-09 19:16:00) [2]


> программа будет через определенные промежутки времени(Timeout)
> импортировать данные из DLL?


Это зависит от конкретной реализации.
Можно "через определенные промежутки времени", можно с использованием того или иного механизма нотификаций ... на то и "универсальность" ..


SerGH   (2006-05-06 19:51:00) [3]

Спасибо


konischev   (2006-05-06 17:47:00) [4]

Ладно будем пробовать. Т.е. как я понял программа будет через определенные промежутки времени(Timeout) импортировать данные из DLL?
А насчет типов я думаю этих хватит, для описания любых данных будь то температура, давление, скорость и т.д. и т.п.


Сергей М.   (2006-05-06 16:03:00) [5]

Один говорит "любые", другой - только "integer, real, string, boolean") ..

Вы уж как-нибудь определитесь с конечным перечнем типов !


> как выкидывать данные из DLL в прогу?


Не надо их "выкидывать".
Следует, вероятно, реализовать и экспортировать ф-ции вида

function GetReceivedDataOfSomeType(Timeout: Integer; var Data: SomeType): Boolean;


SerGH   (2006-05-06 15:55:00) [6]

Любые данные


Konischev   (2006-05-06 15:48:00) [7]

Да, естественно основная программа на Делфи.
Типы: integer, real, string, boolean. С типами мы сами, я думаю, разберемся.
А как выкидывать данные из DLL в прогу? Вот самый главный вопрос...


Сергей М.   (2006-05-06 15:24:00) [8]


> когда DLL примет данные нужно вывести их в основное окно
> программы, как это сделать?


"Основная" программа - это Делфи-приложение ? Или написанное на любом (заранее неизвестном) языке программирования ? Это очень важно ..


> универсальные данные-данные любого типа:integer,string и
> т.п.


В этом плане об "универсальности" не может быть и речи.
Все зависит от конкретного типа данных.


SerGH   (2006-05-06 15:07:00) [9]

универсальные данные-данные любого типа:integer,string и т.п.


konischev   (2006-05-06 14:29:00) [10]

Здравствуйте, Сергей М. Мы с SerGH'ем одногруппники. Ситуация такая. Мы написали две проги которые позволяют обмениваться данными разных типов используя record. Одна прога - сервер, другая - клиент. Преподаватель поставил задачу сделать DLL которая будет передавать данные любого типа используя TCP/IP протокол. Как написать DLL мы примерно знаем, пробовали уже, но возникла проблема ->  когда DLL примет данные нужно вывести их в основное окно программы, как это сделать?


Сергей М.   (2006-05-06 13:46:00) [11]

Странное задание.
"Универсальность" - понятие растяжимое...


SerGH   (2006-05-06 13:41:00) [12]

У меня задание: создание универсальной библиотеки для передачи данных по сетям TCP/IP.


Сергей М.   (2006-05-06 13:20:00) [13]

А каков вообще смысл такой "переделки" ?


Сергей М.   (2006-05-06 13:12:00) [14]

"В лоб" - никак.
Придется практически все "перелопаптить".

Но перед этим следует разработать протокол инф.взаимодействия между хост-приложениями и будущей DLL, которую они будут использовать.
С этого и начни.
Только после этого можно говорить о "переделке".


SerGH   (2006-05-06 13:05:00) [15]

Как из этих программ сделать DLL? Заранее благодарен Вам.


SerGH   (2006-05-06 13:04:00) [16]

Сервер:
unit Server_main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Winsock, ScktComp, StdCtrls, ExtCtrls;

type
 TForm1 = class(TForm)
   Panel1: TPanel;
   Button1: TButton;
   Button2: TButton;
   ListBox1: TListBox;
   Panel2: TPanel;
   ServerSocket1: TServerSocket;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure ServerSocket1ClientRead(Sender: TObject;
   Socket: TCustomWinSocket);
   procedure ServerSocket1ClientDisconnect(Sender: TObject;
   Socket: TCustomWinSocket);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
{Запрашиваем порт}
s := InputBox(' START Server','Enter port:','5577');
if s ='' then
Exit;
{Очистка пользовательского листа}
ListBox1.Items.Clear;
{Устанавливаем порт}
ServerSocket1.Port := StrToInt(s);
{Запускаем сервер}
ServerSocket1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
{Очистка пользовательского листа и остановка сервера}
ListBox1.Items.Clear;
if ServerSocket1.Active then
ServerSocket1.Close;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var s: string;
   i: Integer;
begin
{Сохраняем в s присланную нам строку}
s:= Socket.ReceiveText;
{Если кто-то прислал нам своё имя}
if Copy(s,1,2) = '#N' then begin
Delete(s,1,2);
{Добавляем его в полsьзовательский лист}
ListBox1.Items.Add(s);
{Записываем в s команду для посылки нового списка пользователей}
s:= '#U';
for i :=0 to ListBox1.Items.Count-1 do
s:= s+ListBox1.Items[i]+';';
{...и рассылаем этот список всем клиентам}
for i:=0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(s);
Exit;
end;
{Если кто-то отправил сообщение - рассылаем его всем клиентам}
if (Copy(s,1,2) = '#M')or(Copy(s,1,2) = '#P') then begin
for i :=0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(s);
Exit;
end;
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
 Socket: TCustomWinSocket);
var i: Integer;
begin
 {Кто-то присоединился или отсоединился?  Запрашиваем у всех
  пользователей их имена}
 ListBox1.Items.Clear;
 for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
  ServerSocket1.Socket.Connections[i].SendText('#N');
end;


SerGH   (2006-05-06 13:03:00) [17]

Клиент:
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls, WinSock, Unit2, ScktComp;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Button3: TButton;
   CheckBox1: TCheckBox;
   Edit1: TEdit;
   Label1: TLabel;
   Memo1: TMemo;
   ListBox1: TListBox;
   ClientSocket1: TClientSocket;
   Panel1: TPanel;
   procedure Button2Click(Sender: TObject);
   procedure Button3Click(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure ClientSocket1Connect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Connecting(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Disconnect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
     ErrorEvent: TErrorEvent; var ErrorCode: Integer);
   procedure ClientSocket1Lookup(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
   procedure Edit1KeyDown(Sender: TObject; var Key: Word;
     Shift: TShiftState);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 nickname: string;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
var do_connect: Boolean;
    host,port: string;
begin
{Показываем окно установки соединения с сервером}
 Form2 := TForm2.Create(Application);
 {do_connect = True, если была нажата кнопка Connect}
 do_connect := (Form2.ShowModal = mrOk);
 {заполнение переменных до того, как мы уничтожим форму}
 host := Form2.Edit1.Text;
 port := Form2.Edit2.Text;
 nickname := Form2.Edit3.Text;
 {Уничтожаем форму}
 Form2.Free;
 {Если была нажата кнопка Cancel, то уходим отсюда}
 if not do_connect then
  Exit;
 {Если соединение уже установлено, то обрываем его}
 if ClientSocket1.Active then
  ClientSocket1.Close;
 {Устанавливаем свойства Host и Port}
 ClientSocket1.Host := host;
 ClientSocket1.Port := StrToInt(port);
 {Пытаемся соединиться}
 ClientSocket1.Open;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
{Закрываем соединение (если оно установлено)}
 if ClientSocket1.Active then
  ClientSocket1.Close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
{Если хотим послать приватное сообщение, но не выбрали адресата -
  выводится замечание,затем следует выход из обработчика}
 if (CheckBox1.Checked)and(ListBox1.ItemIndex < 0) then begin
  ShowMessage('At first you should select the user in the User List!');
  Exit;
end;
{Если это приватное сообщение}
 if CheckBox1.Checked then
  s := '#P'+ListBox1.Items[ListBox1.ItemIndex]+';' {добавляем спец.команду и адресат}
 else { Если не приватное}
  s := '#M'; {Просто спец.команду}
 {Добавляем наше имя (от кого) и само сообщение}
 s := s+nickname+';'+Edit1.Text;
 {Посылаем все это по сокету}
 ClientSocket1.Socket.SendText(s);
 {И снова ждем ввода в уже чистом TEdit-е}
 Edit1.Text := '';
 ActiveControl := Edit1;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
{соединились!}
 Memo1.Lines.Insert(0,'connected!');
end;

procedure TForm1.ClientSocket1Connecting(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 {соединяемся...}
 Memo1.Lines.Insert(0,'connecting...');
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
{отсоединились }
 Memo1.Lines.Insert(0,'disconnected');
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
 Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
 var ErrorCode: Integer);
begin
{Если произошла ошибка, выводим ее код в Memo1}
 {Insert вставляет строку в указанную позицию (в данном случае - 0 - в начало)}
 Memo1.Lines.Insert(0,'Socket error ('+IntToStr(ErrorCode)+')');
end;

procedure TForm1.ClientSocket1Lookup(Sender: TObject;
 Socket: TCustomWinSocket);
begin
{Сообщаем о том, что идет поиск хоста}
 Memo1.Lines.Insert(0,'Looking up for server...');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
 Socket: TCustomWinSocket);
 var s,from_,to_: string;
begin
{присваиваем s полученную от сервера строку}
 s := Socket.ReceiveText;
 {Если сервер посылает нам User List}
 if Copy(s,1,2) = '#U' then begin
  Delete(s,1,2);
  {Чистим ListBox1}
  ListBox1.Items.Clear;
  {Добавляем по одному пользователю в список.
  Имена пользователей разделяем знаком ";"}
  while Pos(';',s) > 0 do begin
   ListBox1.Items.Add(Copy(s,1,Pos(';',s)-1));
   Delete(s,1,Pos(';',s));
end;
 Exit;
 end;
 {Если нам прислали общее сообщение (видимое для всех)}
 if Copy(s,1,2) = '#M' then begin
  Delete(s,1,2);
  {Добавляем его в Memo1}
  Memo1.Lines.Insert(0,Copy(s,1,Pos(';',s)-1)+'> '+
                       Copy(s,Pos(';',s)+1,Length(s)-Pos(';',s)));
  Exit;
 end;
 {Если нам прислали запрос на наше имя }
 if Copy(s,1,2) = '#N' then begin
  {Посылаем ответ}
  Socket.SendText('#N'+nickname);
  Exit;
 end;
 {Если прислали приватное сообщение }
 if Copy(s,1,2) = '#P' then begin
  Delete(s,1,2);
  {Выделяем в to_ - кому оно предназначено}
  to_ := Copy(s,1,Pos(';',s)-1);
  Delete(s,1,Pos(';',s));
  {Выделяем в from_ - кем отправлено}
  from_ := Copy(s,1,Pos(';',s)-1);
  Delete(s,1,Pos(';',s));
  {Если оно для нас, или написано нами - добавляем в Memo1}
  if (to_ = nickname)or(from_ = nickname) then
   Memo1.Lines.Insert(0,from_+' (private) > '+s);
  Exit;
 end;
end;
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 {Если была нажата Enter - тоже не
  отказываемся послать сообщение}
 if Key = VK_RETURN then
  Button1.Click;
end;

end.

unit Unit2;

interface

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

type
 TForm2 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Host: TLabel;
   Port: TLabel;
   nickname: TLabel;
   Edit1: TEdit;
   Edit2: TEdit;
   Edit3: TEdit;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.dfm}

end.


Наверх

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