Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.01.2012, 00:14   #1
Mr.Dmitry
Пользователь
 
Аватар для Mr.Dmitry
 
Регистрация: 18.12.2006
Сообщений: 50
По умолчанию Использование потока в dll

Нужно вызвать из dll поток. Обработать в нем данные и вернуть в основной модуль программы.


Вот какая dll получилась



PHP код:
library proc;

uses
  ShareMem
,
  
IdBaseComponent,
  
IdComponent,
  
IdTCPConnection,
  
IdTCPClient,
  
IdHTTP,
  
StdCtrls,
  
IdURI,
  
IdMultipartFormData,
  
ExtCtrls,
  
ComCtrls,
  
Unit1 in 'Unit1.pas';

{
$R *.res}


function 
card_info(httpactionkeycardid:string):mytypestdcallexport;
var
  
NewThreadcards_info;
begin
  NewThread 
:= cards_info.Create(True);
  
NewThread.FreeOnTerminate := True;
  try
    
NewThread.http_thread := http;
    
NewThread.action_thread := action;
    
NewThread.key_thread := key;
    
NewThread.cardid_thread := cardid;
    
NewThread.Priority:=tpLower;
    
NewThread.resume;
  
except on EConvertError do
    
begin
      NewThread
.Free;
      
result.succes:='0';
    
end;
  
end;
  
Result:=res;
end;


Exports card_info;

begin

end

Тут собственно вызывается поток.


PHP код:
unit query_thread;

interface

uses  
  Classes
,
  
IdBaseComponent,
  
IdComponent,
  
IdTCPConnection,
  
IdTCPClient,
  
IdHTTP,
  
StdCtrls,
  
IdURI,
  
IdMultipartFormData,
  
ExtCtrls,
  
ComCtrls,
  
Unit1,
  
nativexml;

type
  cards_info 
= class(TThread)
  private
     
fhttp_thread:string;
     
faction_thread:string;
     
fkey_thread:string;
     
fcardid_thread:string;
  protected
    
procedure card_info;
    
procedure Executeoverride;
  public
     
property http_threadstring write fhttp_thread;
     
property action_threadstring write faction_thread;
     
property key_threadstring write fkey_thread;
     
property cardid_threadstring write fcardid_thread;
     
Constructor Createoverload;   // Этот конструктор использует умолчания
  
end;

procedure cards_info.card_info;
var
dataTIdMultiPartFormDataStream;
xml_string:UTF8String;
IdHTTP1TIdHTTP;
XMLDocTNativeXml//объект XML-документа
NodeListTXmlNodeList;//список узлов
begin
IdHTTP1 
:= TIdHTTP.Create;
  
data := TIdMultiPartFormDataStream.Create;

    
url:=fhttp_thread+'action='+faction_thread+'&session_key=' fkey_thread +
          
'&card='+fcardid_thread+sms;
   
xml_string := UTF8Encode(IdHTTP1.Get(url));
    
end;
     finally
   
data.Free;
  
end;

  
XMLDoc:=TNativeXml.Create;//создаем экземпляр класса

  
XMLDoc.ReadFromString(xml_string);

  if 
XMLDoc.IsEmpty then
    raise Exception
.Create('Пустой XML! Работа прервана!');
   
NodeList:=TXmlNodeList.Create;
   
XMLDoc.Root.FindNodes('balance',NodeList);//получаем список узлов Item
  
res.balance := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('name',NodeList);//получаем список узлов Item
  
res.name := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('surname',NodeList);//получаем список узлов Item
  
res.surname := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('patronymic',NodeList);//получаем список узлов Item
  
res.pat := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('bonus',NodeList);//получаем список узлов Item
  
res.bonus := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('lastdate',NodeList);//получаем список узлов Item
  
res.last := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('regdate',NodeList);//получаем список узлов Item
  
res.reg := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('birth',NodeList);//получаем список узлов Item
  
res.birth := NodeList.items[0].ValueAsUnicodeString;
  
XMLDoc.Root.FindNodes('success',NodeList);//получаем список узлов Item
  
res.succes := NodeList.items[0].ValueAsUnicodeString;
   
end;

procedure cards_info.Execute;
begin
 card_info
;
end

Тут обрабатывается сам поток

PHP код:
unit Unit1;

interface

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

 
type mytype=record
   balance
namesurnamepatbonuslastregbirthsuccestest:string;
  
end;

var
res:mytype;

implementation
end

Только не смейтесь. Этот модуль служит для связи основного модуля библиотеки и потока. Долго ломал голову как передать данные из mytype в основную функцию библиотеки, в итоге додумался до такого варианта )

PHP код:
type
  mytype 
record
    balance
namesurnamepatbonuslastregbirthsuccesteststring;
  
end;
...
procedure TForm1.Button1Click(SenderTObject);
var
  
resmytype;
begin
  res 
:= card_info('сайт.ру/test.php?''323'sesion_key'1111111');
ShowMessage(res.balance);
end
Вот такой вызов dll

при первом нажатии кнопки res.balance возвращается пустым. ((( При повторном возвращается то что нужно.

Последний раз редактировалось Mr.Dmitry; 21.01.2012 в 00:17.
Mr.Dmitry вне форума Ответить с цитированием
Старый 21.01.2012, 00:19   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

код то не ждет пока ктото запишет данные в переменную, а при втором разе там уже есть данные от завершенного первого.

кто ж так асинхронную работу ведет?.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 21.01.2012, 01:05   #3
Mr.Dmitry
Пользователь
 
Аватар для Mr.Dmitry
 
Регистрация: 18.12.2006
Сообщений: 50
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
код то не ждет пока ктото запишет данные в переменную, а при втором разе там уже есть данные от завершенного первого.

кто ж так асинхронную работу ведет?.
До этого не работал с потоками. И поэтому не знаю как нужно и как правильно.


Разве я вот так


Код:
 res.balance := NodeList.items[0].ValueAsUnicodeString;
не записываю данные в переменную?
Mr.Dmitry вне форума Ответить с цитированием
Старый 21.01.2012, 01:32   #4
Mr.Dmitry
Пользователь
 
Аватар для Mr.Dmitry
 
Регистрация: 18.12.2006
Сообщений: 50
По умолчанию

В общем где и что мне нужно записать чтоб сразу при первом обращении мне выдавалось нужная инфа?
Mr.Dmitry вне форума Ответить с цитированием
Старый 21.01.2012, 13:19   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
не записываю данные в переменную?
записываете, только когда это происходит то?

вообще раз вы хотите ждать результата, то тут нет смысла в потоке.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 21.01.2012, 14:51   #6
Mr.Dmitry
Пользователь
 
Аватар для Mr.Dmitry
 
Регистрация: 18.12.2006
Сообщений: 50
По умолчанию

Хмммммм. Первоночально суть вопроса была токова, как сделать чтоб во время отправки запроса через IDhttp форма не подвисала, если интернет слабый, а label выводилось сообщение "Запрос отправлен пожалуйста подождите." Мне сказали что тут без потока не обойтись. Начал разбираться с потоками, и теперь когда уже почти сделал, вы говорите что тут нет смысла в потоке? Так кому верить? Что делать?


PS Я понимаю что я записываю переменную в потоке, и это переменная не передается в основной модуль функции при первом прогоне, при втором прогоне, в перменной уже остались данные от предыдущего запуска и поэтому все выводится. Поэтому как я понимаю нужно как то синхронизировать работу функции потока с основным телом функции в dll. Но как я не пытался это сделать ни черта не выходит. На всех форумах описан элементарный способ синхронизации.
Код:
procedure cards_info.Execute; 
begin 
 synchronize(card_info); 
end;
Но это тоже не помогает

Последний раз редактировалось Mr.Dmitry; 21.01.2012 в 14:56.
Mr.Dmitry вне форума Ответить с цитированием
Старый 21.01.2012, 15:00   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

то что вы хотите делается уж точно не тупым присваиванием, так как оно требет здесь и сейчас.
я говорил про ваш код.

кстати, а затем длл то для потока?

я бы просто отправлял сообщение из потока форме что запрос завершен, и данные теперь актуальный.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 21.01.2012, 15:35   #8
Mr.Dmitry
Пользователь
 
Аватар для Mr.Dmitry
 
Регистрация: 18.12.2006
Сообщений: 50
По умолчанию

Тогда может вы подскажите как это делается?

Как я уже говорил первоначально в длл была функция, которая вызывалась из основной программы. Получала кучу данных и там дальше уже обрабатывались полученные данные и выводились в таблицу. Но было замечено что при слабом интернете программа подвисает. Провисания были не кретичны, но пользователем же не объяснишь что все нормально, щас все путем будет. Был начат поиск устранения такого провисания. На другом форуме сказали что без потоков не обойтись. До этого я ни когда не работал с потоками и разбираюсь с ними около одной недели, смог сделать код который описан в первом посте. Поэтому может быть ты уже ткнешь меня носом и скажешь как же нужно это сделать если не тупым присвоением? Как вернуть данные res.balance, res.name, res.surname и т.д из dll в основную форму используя поток?

PS Прикрепил файл с проектом
Вложения
Тип файла: rar test.rar (782.4 Кб, 6 просмотров)

Последний раз редактировалось Mr.Dmitry; 21.01.2012 в 16:13.
Mr.Dmitry вне форума Ответить с цитированием
Старый 22.01.2012, 14:53   #9
Mr.Dmitry
Пользователь
 
Аватар для Mr.Dmitry
 
Регистрация: 18.12.2006
Сообщений: 50
По умолчанию

С исходниками стало еще тяжелее помочь? (
Mr.Dmitry вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание потока в dll kenji Общие вопросы Delphi 3 04.11.2011 13:13
bass.dll Скорость мать его потока... Дворник Мультимедиа в Delphi 5 24.08.2010 09:37
Использование Dll xmaksimca Общие вопросы Delphi 0 16.05.2010 18:36
Использование метода free после завершения потока Denager Общие вопросы Delphi 4 29.08.2008 10:13
микшер на два потока в проигрывателе музыки. проигрыватель сделан на основе библиотеки Bass.dll D-fens Мультимедиа в Delphi 4 08.06.2007 20:36