Текущий архив: 2004.07.04;
Скачать: CL | DM;
Вниз
Как передав SendMessage указатель на строку Найти похожие ветки
← →
}|{yk © (2004-06-22 12:25) [0]преобразовать в функции обработчике в stroky?
← →
Anatoly Podgoretsky © (2004-06-22 12:26) [1]S := P
← →
MBo © (2004-06-22 12:29) [2]в рамках одного процесса?
← →
wicked © (2004-06-22 12:31) [3]если в пределах процесса:
S := PChar(LParam);
UniqueString(S); // перестрахуемся... :)
если между процессами - атомы, memory mapped files, файлы...
← →
}|{yk © (2004-06-22 12:33) [4]Между разными потоками
← →
PVOzerski © (2004-06-22 12:35) [5]>Между разными потоками
Если в пределах одного процесса, то адресное пространство одно и, соответственно, переданный указатель не теряет смысла.
← →
wicked © (2004-06-22 12:36) [6]тогда подойдет [3]...
хотя это зависит от того, как и какую строку передали в SendMessage и кто её должен освободить в конце - отправитель или получатель...
← →
Тимохов © (2004-06-22 12:38) [7]
> если между процессами - атомы, memory mapped files, файлы...
+wm_copydata
← →
PVOzerski © (2004-06-22 12:39) [8]>и кто её должен освободить в конце - отправитель или получатель...
А вот это уже зависит от того, общий ли менеджер памяти.
← →
Serginio666 (2004-06-22 14:41) [9]Создай класс
TMyString = class
str:String;
end;
или PString = ^String;
И передавай экземпляр класса. Дело в том, что передаваяемая строка может выйти из области видимости(в рамках одного процесса) и самопроизвольно разрушиться.
Между процессам кроме перечисленного WMCopy
← →
Ega23 © (2004-06-22 14:43) [10]Serginio666 (22.06.04 14:41) [9]
Ну ты силён!!!!!!!
← →
han_malign © (2004-06-22 14:56) [11]>Serginio666
>может выйти из области видимости
- SendMessage - выполняется "синхронно"(в контексте основного потока, но с ожиданием обработки команды). К тому же передача экземпляра класса, и дополнительные манипуляции с указателями(скажем в случае Post[Thread]Message) не спасут - тоже "может выйти из области видимости"...
З.Ы. }|{yk © - если в строке допустимы терминирующие символы(#0), то можно, скажем в wParam, передавать длину - тогда SetString(S,PChar(lParam),wParam), или воспользоваться передачей указателя на структуру...
З.З.Ы. "UniqueString(S); // перестрахуемся... :)" - совершенно лишнее, новая строка аллокируется на /S := PChar(LParam)/SetString(...)/
← →
Serginio666 (2004-06-22 15:02) [12]>han_malign
Согласен , данное утверждение относится к PostMessage, но
при манипуляции с классом или указателем мы увеличиваем счетчик ссылок строки предотваращая ее разрушение.
То есть
K:= TMyString.Create;
K.Str:=SourceStr;
так и с указателем.
(Конечноможно ее и вручную увеличить но это не совсем правильный подход).
← →
}|{yk © (2004-06-22 15:36) [13]>кто её должен освободить в конце
Т.е.? Менеджер памяти Делфи не сделает это за меня?
>передаваяемая строка может выйти из области видимости(в рамках одного процесса) и самопроизвольно разрушиться.
В каком случае? Протестировал, вроде все нормально. Раньше пытался в потоке менять надписи, и иногда получал ошибки. Теперь вроде нормально
← →
Serginio666 (2004-06-22 15:49) [14]Менеджер памяти ничего сам не уничтожает.
Строка уничтожается при достижении RefCount=0;
Наступить на грабли передавая ее как указатель очень легко,
впрочем как и с динамическими массивами и интерфейсами поддерживающими подсчет ссылок.
для примера
Procedure p(p:Pointer)
var s:String;
Begin
Pointer(S):=P;
//.....
end;
По выходу из процедуры счетчик уменьшится и если он стал равен 0 то разрушиться. И вызывающем методе получишь ссылку на несуществующую память.
Здесь еще есть эффект менеджера памяти Delphi, т.к. сама память не уничтожается а помечается как не используемая
http://www.rsdn.ru/article/Delphi/memmanager.xml
Вот в общем, что и хотел сказать.
← →
Anatoly Podgoretsky © (2004-06-22 15:52) [15]}|{yk © (22.06.04 15:36) [13]
В том контексте как ты задал вопрос сделает, вне зависимости от того какой менеджер.
← →
panov © (2004-06-22 15:53) [16]>}|{yk © (22.06.04 15:36) [13]
Непонятно, как ты используешь SendMessage для посылки сообщения в поток.
Для этого используется PostThreadMessage:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const WM_STRING=WM_USER+1;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TTest=class(TThread)
FListBox: TListBox;
FMessage: String;
protected
procedure Execute; override;
public
constructor Create(const aLB: TListBox);
procedure Display;
end;
TSender=class(TThread)
FThreadId: THandle;
protected
procedure Execute; override;
public
constructor Create(const aThreadId: THandle);
end;
var
Form1: TForm1;
test: TTest;
implementation
{$R *.dfm}
constructor TSender.Create(const aThreadId: THandle);
begin
inherited Create(True);
FreeOnTerminate := True;
FThreadId := aThreadId;
Resume;
end;
procedure TSender.Execute;
var
s: String;
i: Integer;
begin
for i := 0 to 1000 do
begin
s := IntToStr(i)+" - ????????? ?? ??????? ??????";
PostThreadMessage(FThreadId,WM_STRING,Integer(PChar(s)),0);
end;
PostThreadMessage(FThreadId,WM_QUIT,Integer(@s[1]),0);
end;
constructor TTest.Create(const aLB: TListBox);
begin
inherited Create(True);
FreeOnTerminate := True;
FListBox := aLB;
Resume;
end;
procedure TTest.Display;
begin
FListBox.Items.Add(FMessage);
end;
procedure TTest.Execute;
var
Msg: TMsg;
begin
while GetMessage(Msg,0,0,0) do
begin
case Msg.message of
WM_STRING:
begin
FMessage := PChar(Msg.wParam);
Synchronize(Display);
end;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Test := TTest.Create(ListBox1);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
TSender.Create(test.ThreadID);
end;
end.
← →
}|{yk © (2004-06-22 16:07) [17]Не в поток, а из потока в главный поток приложения
Страницы: 1 вся ветка
Текущий архив: 2004.07.04;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.052 c