Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 6

Автор: Frodo_Torbins
Дата сообщения: 31.03.2011 13:02
Man_Without_Face
Неплохо бы указать соглашения вызова. Кроме того в делфи уже есть тип TProc, проверьте какой из них используется в этом вашем "другом юните".
Автор: Man_Without_Face
Дата сообщения: 31.03.2011 16:16
Frodo_Torbins

Цитата:
Кроме того в делфи уже есть тип TProc

да спасибо, разобрался, помогло

Цитата:
а еще после закрытия exe, dll не выгружается (по логам вижу)

убрал и в dll и в exe ShareMem, вроде помогло.

Да и все это у меня работает через потоки в Dll (CriticalSection).


Цитата:
Неплохо бы указать соглашения вызова.

Это как и для чего?


Автор: Frodo_Torbins
Дата сообщения: 31.03.2011 17:18
Man_Without_Face
Цитата:
Это как и для чего?

Это на тот случай, если вдруг понадобится написать плагин на другом языке. Соглашения прописываются и в exe, рядом с объявлением процедуры, и в dll, рядом с объявлением типа.
Автор: GRom V
Дата сообщения: 06.04.2011 14:50
подскажите ктонить...
Begin
Reg.RootKey:=HKEY_LOCAL_MACHINE;
Reg.OpenKey('\Software\Microsoft\Windows',True);
Reg.WriteString('4',Application.ExeName);
Reg.Free;
end;

в windows 7 это делается под админом. Соответственно если запускать от обычного юзера прога выдает ошибку, т.к. нет доступа
Как сделать чтоб ошибок вооще не выдавало?
т.е если не удалось открыть то и фиг с ним...???
Автор: psa1974
Дата сообщения: 06.04.2011 15:13
GRom V
Самое простое решение - заключить в блок try... except и при необходимости обрабатывать исключение:
[more=пример]
Код: Reg:= TRegistry.Create;
try
Reg.RootKey:=HKEY_LOCAL_MACHINE;
try
Reg.OpenKey('\Software\Microsoft\Windows',True);
Reg.WriteString('4',Application.ExeName);
except
// если надо - как-то обрабатываешь исключение, например:
on E: ERegistryException do ShowMessage(E.Message);
end;
finally
Reg.Free;
end;
Автор: GRom V
Дата сообщения: 07.04.2011 03:55
psa1974
Спасибки
Автор: Man_Without_Face
Дата сообщения: 07.04.2011 09:14
Доброго времени суток, подскажите что делают не так (в итоге получаю не те значения):
[more]
procedure OnReceivePacket(FromHostIP: Uint64; ReceiveData: pointer; ReceiveDataLength: cardinal;
ResponseData: pByte; ResponseDataLength: pCardinal);
var RD: pointer;
begin
getmem(RD, sizeof(ReceiveData^));
move(ReceiveData^, RD^, sizeof(ReceiveData^));
NewThread(FromHostIP, RD, ReceiveDataLength); //тут создаю поток
end;
-------------------------------------
procedure NewThread(FromHostIP: Uint64; ReceiveData: pointer; ReceiveDataLength: cardinal);
var
CreateNewThread: TNewThread; //новый поток
begin
CreateNewThread := TNewThread.Create(true); //создание
CreateNewThread.FreeOnTerminate := true; //уничтожение
CreateNewThread.Priority := tpNormal; //приоритет
CreateNewThread.Resume; //запуск
//Передача параметров
CreateNewThread.FromHostIP := FromHostIP;
move(ReceiveData^, CreateNewThread.ReceiveData^, sizeof(ReceiveData^));
CreateNewThread.ReceiveDataLength := ReceiveDataLength;
end;
----------------------------------------
procedure TNewThread.Execute;
var
ppUin: cardinal;
pNum: byte;
vData: PPing2;
begin
CriticalSection.Enter;
Move(ReceiveData^, ppUin, 4);
WriteLog('Универсальный идентификатор - ' + inttostr(ppUin));
if ppUin = 11111111 then
begin
//inc(cardinal(ReceiveData), 4);
//Move(ReceiveData, pNum, 1);
//WriteLog('Код команды - '+inttostr(pNum));
pNum := 1;
case pNum of
1:try
WriteLog('Пинг от:');
new(vData);
move(ReceiveData^, vData^, sizeof(ReceiveData^));
WriteLog('Центр '+ inttostr(vData^.MyCenter));
WriteLog('Объект '+ inttostr(vData^.MyObject));
WriteLog('Ip '+ inttostr(FromHostIP));
finally
Dispose(vData);
end;
end;
end;
dispose(ReceiveData);
CriticalSection.Leave;
end;
-------------------------------------
TPing2 = record
Uin: cardinal; // уникальный идентификатор
Num: byte; // номер команды
Code: byte; // код команды
MyCenter: Word;
MyObject: Word;
--------------------------------------
type
TNewThread = class(TThread)
public
{ Private declarations }
protected
FromHostIP: Uint64;
ReceiveData: pointer;
ReceiveDataLength: cardinal;
procedure Execute; override;
end;
[/more]
Все в Dll на Delphi2009.
Автор: greenpc
Дата сообщения: 07.04.2011 11:03
Man_Without_Face
первое что бросилось в глаза

Код: ReceiveData: pointer
Автор: Man_Without_Face
Дата сообщения: 07.04.2011 12:11
greenpc
Да, спасибо. Входные параметры будут заполняться с другой dll. А пока я на таймере моделирую. Не совсем понял почему так нельзя: разыменовываеш указатель, т.е. получаеш доступ к данным куда он указывает, так почему нельзя их размер узнать?
--------------------------
но дальше еще хуже. AV валят один за другим.
--------------------------
Такой вопрос: в дебагере при наведении курсора на указатель, показывается адрес памяти (в 16 системе) указателя или адрес данных куда он указывает.
И еще: move(ReceiveData^, RD^, ReceiveDataLength); здесь указатели нужно разыменовывать или нет (move(ReceiveData, RD, ReceiveDataLength);) ?
Автор: greenpc
Дата сообщения: 07.04.2011 12:39
Man_Without_Face

Код: var
iValue : integer;
pIntValue : pointer;
pmp : ^integer;
begin
iValue := 2001;
pIntValue := @iValue; // равно нулю
pmp := @iValue; // но здесь равно 4 (указатель на тип)
ShowMessage(IntToStr(SizeOf(pIntValue^)));
ShowMessage(IntToStr(SizeOf(pmp^)));
end;
Автор: Man_Without_Face
Дата сообщения: 07.04.2011 12:52
greenpc
при передачи параметров в поток тут av (write of adress 00000000). Я так понимаю пытаюсь записать в несуществующий указатель!? Но тогда как? FromHostIP передается нормально.

move(ReceiveData^, CreateNewThread.ReceiveData^, ReceiveDataLength);
Автор: greenpc
Дата сообщения: 07.04.2011 13:07
Man_Without_Face
почему идет запуск потока перед передачей парам-ов ему?
ЗЫ: обновите Ваш код чтобы было что смотреть
ЗЫ2: отладку удобнее вести без потоков.
создайте процедуру с теме же парам-ми - нагляднее будет
Автор: Man_Without_Face
Дата сообщения: 07.04.2011 14:10
greenpc
обновленный код:
[more]
procedure OnReceivePacket(FromHostIP: Uint64; ReceiveData: pointer; ReceiveDataLength: cardinal;
ResponseData: pByte; ResponseDataLength: pCardinal);
var RD: pointer;
begin
getmem(RD, ReceiveDataLength);
move(ReceiveData^, RD^, ReceiveDataLength);
NewThread(FromHostIP, RD, ReceiveDataLength);
end;
-------------------------
procedure NewThread(FromHostIP: Uint64; ReceiveData: pointer; ReceiveDataLength: cardinal);
var
CreateNewThread: TNewThread; //новый поток
begin
CreateNewThread := TNewThread.Create(true); //создание
CreateNewThread.FreeOnTerminate := true; //уничтожение
CreateNewThread.Priority := tpNormal; //приоритет
//Передача параметров
CreateNewThread.FromHostIP := FromHostIP;
move(ReceiveData^, CreateNewThread.ReceiveData^, ReceiveDataLength);
CreateNewThread.ReceiveDataLength := ReceiveDataLength;

CreateNewThread.Resume; //запуск
end;
--------------------------
procedure TNewThread.Execute;
var
ppUin: cardinal;
pNum: byte;
vData: PPing2;
begin
CriticalSection.Enter;
WriteLog('OnReceivePacket:');
WriteLog('От кого - '+inttostr(FromHostIP));
WriteLog('Длинна данных - '+inttostr(ReceiveDataLength));

Move(ReceiveData^, ppUin, 4);

WriteLog('Универсальный идентификатор - ' + inttostr(ppUin));
if ppUin = 11111111 then
begin
//inc(cardinal(ReceiveData), 4);
//Move(ReceiveData, pNum, 1);
//WriteLog('Код команды - '+inttostr(pNum));
pNum := 1;
case pNum of
1:try
WriteLog('Пинг от:');
new(vData);
move(ReceiveData^, vData^, ReceiveDataLength);

WriteLog('Центр '+ inttostr(vData^.MyCenter));
WriteLog('Объект '+ inttostr(vData^.MyObject));
WriteLog('Ip '+ inttostr(FromHostIP));
finally
Dispose(vData);
end;
end;
end;
dispose(ReceiveData);
CriticalSection.Leave;
end;
--------------------------
type
TNewThread = class(TThread)
public
{ Private declarations }
protected
FromHostIP: Uint64;
ReceiveData: pointer;
ReceiveDataLength: cardinal;
procedure Execute; override;
end;
[/more]
Автор: greenpc
Дата сообщения: 07.04.2011 14:28
Man_Without_Face
задать размер(выделить память) CreateNewThread.ReceiveData
Автор: Man_Without_Face
Дата сообщения: 07.04.2011 14:46
greenpc
Огромное спасибо, все ок.
Только не понимаю: я же память уже выделял, и просто перекидывал между указателями!?
Правильно ли я теперь освобождаю память?
freemem(ReceiveData); в procedure TNewThread.Execute;
И нужно ли здесь то же освобождать? procedure NewThread(FromHostIP: Uint64; ReceiveData: pointer; ReceiveDataLength: cardinal);
Добавилось только: getmem(CreateNewThread.ReceiveData, ReceiveDataLength);

И еще небольшой вопросик, нигде не нашел:
Как прочить из ReceiveData 5й байт
Move(ReceiveData^, pNum, ???);
Автор: greenpc
Дата сообщения: 07.04.2011 14:56
Man_Without_Face

Цитата:
я же память уже выделял, и просто перекидывал между указателями

help(f1) move - Copies bytes from a source to a destination.
Цитата:
И нужно ли здесь то же освобождать
да. Вы же выделили память.
Цитата:
Как прочить из ReceiveData 5й байт

думаю так
Код: Move((ReceiveData+5*sizeof(pNum))^, pNum, sizeof(pNum));
Автор: Frodo_Torbins
Дата сообщения: 07.04.2011 15:01
Man_Without_Face
Чтобы "перекидывать между указателями" надо их присваивать: "CreateNewThread.ReceiveData := ReceiveData;".
Для освежения памяти: http://www.transl-gunsmoker.ru/2009/09/blog-post.html
Автор: greenpc
Дата сообщения: 07.04.2011 15:06
Frodo_Torbins
для потоков будет ошибка
Автор: Frodo_Torbins
Дата сообщения: 07.04.2011 15:24
greenpc
К строке "move(ReceiveData^, RD^, ReceiveDataLength);" у меня нет никаких замечаний. Я о втором move в процедуре NewThread.
Автор: greenpc
Дата сообщения: 07.04.2011 15:31
Frodo_Torbins
недоглядел. извиняюсь.
Автор: Man_Without_Face
Дата сообщения: 07.04.2011 15:52
greenpc
Frodo_Torbins
Ок, спасибо.
Я понимаю так [more]
procedure NewThread(FromHostIP: Uint64; ReceiveData: pointer; ReceiveDataLength: cardinal);
var
CreateNewThread: TNewThread; //новый поток
begin
CreateNewThread := TNewThread.Create(true); //создание
CreateNewThread.FreeOnTerminate := true; //уничтожение
CreateNewThread.Priority := tpNormal; //приоритет
//Передача параметров
CreateNewThread.FromHostIP := FromHostIP;
//getmem(CreateNewThread.ReceiveData, ReceiveDataLength);
//move(ReceiveData^, CreateNewThread.ReceiveData^, ReceiveDataLength);
CreateNewThread.ReceiveData := ReceiveData;
CreateNewThread.ReceiveDataLength := ReceiveDataLength;
CreateNewThread.Resume; //запуск
//freemem(ReceiveData);
end;
[/more]
в procedure TNewThread.Execute; освобождать память так или что то лишнее?
Dispose(vData);
freemem(ReceiveData);

greenpc

Цитата:
Move((ReceiveData+5*sizeof(pNum))^, pNum, sizeof(pNum));

к сожалению так не работает...
Автор: Frodo_Torbins
Дата сообщения: 07.04.2011 16:16
Man_Without_Face
В старших версиях наверно нужны дополнительные приведения типов: "Move(Pointer(Integer(ReceiveData)+5*sizeof(pNum))^, pNum, sizeof(pNum));".
Автор: Man_Without_Face
Дата сообщения: 07.04.2011 16:46
Frodo_Torbins
Почему то всегда получается единица...
В моем коде это строка идет после проверки уина (ppUin).
Автор: Frodo_Torbins
Дата сообщения: 07.04.2011 16:55
Man_Without_Face
Попробуйте куда-нибудь вывести весь буфер.
А вообще работа с указателями всегда выглядит страшно и несет в себе много скрытых глюков. Я бы сразу же избавился от них примерно так:
Код: type
TData = packed array of Byte;
//...
var
RD: TData;
//...
SetLength(RD, ReceiveDataLength);
move(ReceiveData^, RD[1], ReceiveDataLength);
Автор: greenpc
Дата сообщения: 07.04.2011 18:18
Man_Without_Face
сейчас из дома дельфей нет. ошибка скорее всего то что смещение 5*size
правильно будет (5-1)*sizeof() - т.е. 4 байта пропускаем с 5 читаем.
или (ReceiveData+sizeof(ppUin))^
Автор: greenpc
Дата сообщения: 08.04.2011 07:59
Man_Without_Face

Код: mas: array of byte;
mybyte : Byte;
begin
SetLength(mas,7);
for i := low(mas) to High(mas) do mas[i]:=i;
pIntValue :=@(mas[1]);
move((pointer(integer(pIntValue)+1))^, mybyte, sizeof(mybyte));
ShowMessage(IntToStr(mybyte));
end;
Автор: Frodo_Torbins
Дата сообщения: 08.04.2011 10:03
greenpc
Да, вроде бы так немного лучше. Хотя лично мне вообще работать с указателями не нравится, да и на выходе компилятор выдаст примерно тоже что и с массивом. Может даже массив сумеет оптимизировать.
Автор: KorolCOOL
Дата сообщения: 09.04.2011 14:28
Народ можно ли в Делфи создать программу, в которой можно было бы форматировать текст. Т.е хотя бы жалкое подобие WordPada реально сделать? Чтобы можно было, к примеру, слово курсивом выделить или жирным его сделать, размер шрифта изменить...

По идее это нужно будет использовать какой-то язык разметки для текста документа? Покопался в интернете, в одном месте кому-то так и советовали, дескать используй HTML теги, а потом пусть все это дело посылается в браузер. А иные вариаты существуют? Может какую библиотеку компонентов нужно притулить?
Автор: Frodo_Torbins
Дата сообщения: 09.04.2011 14:34
KorolCOOL
Вместе с делфи поставляется несколько стандартных демок. Откройте демку RichEdit. Это то что вам нужно?
Автор: KorolCOOL
Дата сообщения: 10.04.2011 06:53
Извиняюсь, что сразу не указал, но мне неободимо, чтобы отформатированный текст потом сохранялся в БД и оттуда же потом извлекался для просмотра и редакции. Насчет RichEdit спасибо, будем разбираться.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.