Форум: "WinAPI";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];
ВнизПересылка записи между процессами Найти похожие ветки
← →
FunkyByte © (2006-03-26 23:22) [0]Доброго времени суток, уважаемые мастера. Возникла необходимость пересылать из одного процесса в другой данные сложной структуры. А именно записи:
TSendedRecord = packed record
Sender, Mess: String;
end;
Проделать эту операцию я решил при помощи сообщения WM_COPYDATA. В тестовых целях склепал 2 простенькие программки: отправитель и получатель.
Отправитель (консоль):
var
Str: String;
CopyData: TCopyDataStruct;
SendedRecord: TSendedRecord;
begin
ReadLn(Str);
OemToChar(PChar(Str),PChar(Str));
SendedRecord.Sender:=Str;
ReadLn(Str);
OemToChar(PChar(Str),PChar(Str));
SendedRecord.Mess:=Str;
CopyData.cbData:=SizeOf(SendedRecord);
CopyData.lpData:=@SendedRecord;
SendMessage(FindWindow("TForm1","Form1"),WM_COPYDATA,0,LParam(@CopyData));
end.
Получатель:
type
...
PSendedRecord = ^TSendedRecord;
...
TForm1 = class(TForm)
private
procedure WMCopyData (var Msg: TMessage); message WM_COPYDATA;
...
end;
...
procedure TForm1.WMCopyData(var Msg: TMessage);
var
pdsDataPack: PCopyDataStruct;
DataPack: CopyDataStruct;
pdrDataRec: PSendedRecord;
DataRec: TSendedRecord;
begin
pdsDataPack:=PCopyDataStruct(Msg.LParam);
DataPack:=pdsDataPack^;
pdrDataRec:=PSendedRecord(DataPack.lpData);
DataRec:=pdrDataRec^;//ОШИБКА!!!
...
end;
Когда при обработке сообщения WM_COPYDATA я пытаюсь обратиться к передаваемой записи через указатель на неё возникает Accec Violation. В чём тут проблема? И как с ней бороться? Заранее благодарен.
← →
MBo © (2006-03-27 08:25) [1]В передаваемой записи у тебя содержатся длинные строки, т.е. указатели на данные в первом процессе, которые бессмысленны во втором процессе.
Придется сформировать такой блок данных, в котором все данные лежат вместе. Проще всего - если строки короче 256 символов - использовать Shortstring.
← →
FunkyByte © (2006-03-27 11:27) [2]Действительно, использование ShortString решило проблему. Спасибо.
← →
Lucefer (2006-03-28 12:59) [3]Ты передаешь в поток адрес на переменную основного потока, это может привести к печальным последствиям.
Я делаю по другому. Выделяю кусок памяти, копирую туда строку, передаю указатель на строку. потом в потоке его уничтожаю.function DuplicateStrToPChar(const inStr:String):PChar;
var f, s :integer;
begin
//Для сообщения в "родительский" поток информации о клиенте.
s:=Length(inStr);
getmem(Result, s+1);
for f:= 0 to s-1 do
Result[f]:=inStr[f+1];
Result[s]:=#0;
end;
...
PostMessage(WinHandle,
WM_MY_CMD,
Integer(DuplicateStrToPChar(SomeStr1))),
Integer(DuplicateStrToPChar(SomeStr2)));
...
var
pLStr, pWstr :PChar;
...
pWstr:=PChar(Msg.WParam);
pLStr:=PChar(Msg.LParam);
try
...
finally
if Assigned(pWstr) then begin FreeMem(pWstr); pWstr:=nil; end;
if Assigned(pLStr) then begin FreeMem(pLStr); pLStr:=nil; end;
end;
← →
MBo © (2006-03-28 13:12) [4]>Lucefer (28.03.06 12:59) [3]
У автора другая ситуация - межпроцессное взаимодействие
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];
Память: 0.45 MB
Время: 0.008 c