Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.01;
Скачать: CL | DM;

Вниз

КАК принять данные из DLL ?   Найти похожие ветки 

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

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


 
SerGH ©   (2006-05-06 13:03) [1]

Клиент:
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.


 
SerGH ©   (2006-05-06 13:04) [2]

Сервер:
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:05) [3]

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


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

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

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


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

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


 
SerGH ©   (2006-05-06 13:41) [6]

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


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

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


 
konischev ©   (2006-05-06 14:29) [8]

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


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

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


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


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


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


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


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


 
Konischev ©   (2006-05-06 15:48) [11]

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


 
SerGH ©   (2006-05-06 15:55) [12]

Любые данные


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

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

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


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


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

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


 
konischev ©   (2006-05-06 17:47) [14]

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


 
SerGH ©   (2006-05-06 19:51) [15]

Спасибо


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


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


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


 
Slym ©   (2006-05-10 05:49) [17]

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

WinSock это умеет :)

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

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



Страницы: 1 вся ветка

Текущий архив: 2006.10.01;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.027 c
2-1157492671
RASkov
2006-09-06 01:44
2006.10.01
Масштабирование


15-1158041653
wwwrr
2006-09-12 10:14
2006.10.01
Вопрос...


15-1157697554
Мазут Береговой
2006-09-08 10:39
2006.10.01
Почему автомеханики любят женщин


2-1157969374
Alex_KV
2006-09-11 14:09
2006.10.01
Про SetLength


2-1157796355
max1991
2006-09-09 14:05
2006.10.01
Подскажите пожалуйста, как правильно перевести Char to STR