Глюки Lazarus
Модератор: Модераторы
Глюки Lazarus
Такая проблема проявилась.
Есть небольшой проект.
Одно время он компилировался и работал нормально. Какое-то время я его не использовал.
Тут внес небольшие изменения, и часть кода просто не выполняется....
Т.е. как пример - при запуске программы, вызываю процедуру, в которой в Memo добавляются строки. Часть строк добавляется, а часть нет.
Пробовал: Файл - очистить каталог - проблема осталась.
Добавил на форму кнопку, в которой вызываю ту же процедуру - она отрабатывает нормально.
В чем проблема? (Просто подозреваю, что и в крупном проекте несмотря на внесенные изменения, выполняется как бы старый код...)
Есть небольшой проект.
Одно время он компилировался и работал нормально. Какое-то время я его не использовал.
Тут внес небольшие изменения, и часть кода просто не выполняется....
Т.е. как пример - при запуске программы, вызываю процедуру, в которой в Memo добавляются строки. Часть строк добавляется, а часть нет.
Пробовал: Файл - очистить каталог - проблема осталась.
Добавил на форму кнопку, в которой вызываю ту же процедуру - она отрабатывает нормально.
В чем проблема? (Просто подозреваю, что и в крупном проекте несмотря на внесенные изменения, выполняется как бы старый код...)
Не видя код это гадание.
Как доступ к Мемо осуществляется, как вывод идет, где какие обновления....
"-Помогите, мотоцикл не заводится! -Бензин есть? Нейтраль включил? Аварийный стоп выключен? Почему ключи от другого мотоцикла вставляешь?"
Как доступ к Мемо осуществляется, как вывод идет, где какие обновления....
Код: Выделить всё
procedure TForm1.GetName;
Var
vSizet : DWord;
vPWChart: PWideChar;
vNamePC,
vNameUser : String;
I : DWord;
vWNameUser,
vWNamePC : WideString;
begin
vSizet := 1024;
vPWChart := GetMem(vSizet);
// получаем имя ПК
if GetComputerNameW(vPWChart, vSizet) then
begin
SetString(vWNamePC, vPWChart, vSizet);
vNamePC := UTF8Encode(vWNamePC);
end
else
vNamePC := '';
Memo1.Lines.Add('Имя ПК: '+vNamePC);
// получаем логин !!!
vSizet := 1024;
if GetUserNameW(vPWChart, vSizet) then
begin
SetString(vWNameUser, vPWChart, vSizet);
vNameUser := UTF8Encode(vWNameUser);
end
else
begin
vNameUser := '';
Memo1.Lines.Add('LastError: ' + SysErrorMessageUTF8(GetLastError));
end;
Memo1.Lines.Add('GetUserName: '+vNameUser);
for i:= 0 to 12 do
begin
vSizet := 1024;
if GetUserNameExW(I,vPWChart, vSizet) then
begin
SetString(vWNameUser, vPWChart, vSizet);
vNameUser := UTF8Encode(vWNameUser);
end
else
begin
vNameUser := '';
vNameUser := 'LastError: ' + SysErrorMessageUTF8(GetLastError);
end;
Memo1.Lines.Add('GetUserNameEx '+IntToStr(I)+': '+vNameUser);
end;
FreeMem(vPWChart);
end;
Если вызываю в FormCreate , то то что в for i:= 0 to 12 do не работает.
Angel_19 писал(а):Если вызываю в FormCreate , то то что в for i:= 0 to 12 do не работает.
Нет, все что после
Код: Выделить всё
Memo1.Lines.Add('GetUserName: '+vNameUser);
Не отображается в самом мемо. Если ее закомментируешь, то работать будет.
Там что то в переменной передается, что мешает Мемо работать.
В переменной там обычная строка.
Добавлено спустя 4 минуты 7 секунд:
Там в конце строки идет символ: #0 , он то все и портит.
если изменить код так, то все работает сразу:
Добавлено спустя 6 минут 43 секунды:
Но если оставить преждний код, и на форму добавить кнопку, и вызвать эту процедуру из кнопки, то все отрабатывает нормально, хотя символ #0 есть в злополучной строке...
Добавлено спустя 19 минут 56 секунд:
Правильный код:
Размер использованного буфера возвращаемый системными функциями GetUserNameW и GetUserNameExW больше на 1.
Добавлено спустя 46 секунд:
Sharfik - спасибо!
Добавлено спустя 4 минуты 7 секунд:
Там в конце строки идет символ: #0 , он то все и портит.
если изменить код так, то все работает сразу:
Код: Выделить всё
procedure TForm1.GetName;
Var
vSizet : DWord;
vPWChart: PWideChar;
vNamePC,
vNameUser : String;
I : DWord;
vWNameUser,
vWNamePC : WideString;
begin
vSizet := 1024;
vPWChart := GetMem(vSizet);
// получаем имя ПК
if GetComputerNameW(vPWChart, vSizet) then
begin
SetString(vWNamePC, vPWChart, vSizet);
vNamePC := UTF8Encode(vWNamePC);
end
else
vNamePC := '';
Memo1.Lines.Add('Имя ПК: '+vNamePC);
// получаем логин !!!
vSizet := 1024;
if GetUserNameW(vPWChart, vSizet) then
begin
// SetString(vWNameUser, vPWChart, vSizet);
// vNameUser := UTF8Encode(vWNameUser);
vNameUser := UTF8Encode(WideString(vPWChart));
end
else
begin
vNameUser := '';
Memo1.Lines.Add('LastError: ' + SysErrorMessageUTF8(GetLastError));
end;
vNameUser := 'GetUserName: '+vNameUser;
Memo1.Lines.Add(vNameUser);
for i:= 0 to 12 do
begin
vSizet := 1024;
if GetUserNameExW(I,vPWChart, vSizet) then
begin
SetString(vWNameUser, vPWChart, vSizet);
vNameUser := UTF8Encode(vWNameUser);
end
else
begin
vNameUser := '';
vNameUser := 'LastError: ' + SysErrorMessageUTF8(GetLastError);
end;
Memo1.Lines.Add('GetUserNameEx '+IntToStr(I)+': '+vNameUser);
end;
FreeMem(vPWChart);
end;
Добавлено спустя 6 минут 43 секунды:
Но если оставить преждний код, и на форму добавить кнопку, и вызвать эту процедуру из кнопки, то все отрабатывает нормально, хотя символ #0 есть в злополучной строке...
Добавлено спустя 19 минут 56 секунд:
Правильный код:
Код: Выделить всё
procedure TForm1.GetName;
Var
vSizet : DWord;
vPWChart: PWideChar;
vNamePC,
vNameUser : String;
I : DWord;
vWNameUser,
vWNamePC : WideString;
begin
vSizet := 1024;
vPWChart := GetMem(vSizet);
// получаем имя ПК
if GetComputerNameW(vPWChart, vSizet) then
begin
SetString(vWNamePC, vPWChart, vSizet);
vNamePC := UTF8Encode(vWNamePC);
end
else
vNamePC := '';
Memo1.Lines.Add('Имя ПК: '+vNamePC);
// получаем логин !!!
vSizet := 1024;
if GetUserNameW(vPWChart, vSizet) then
begin
SetString(vWNameUser, vPWChart, vSizet-1);
vNameUser := UTF8Encode(vWNameUser);
end
else
begin
vNameUser := '';
Memo1.Lines.Add('LastError: ' + SysErrorMessageUTF8(GetLastError));
end;
vNameUser := 'GetUserName: '+vNameUser;
Memo1.Lines.Add(vNameUser);
for i:= 0 to 12 do
begin
vSizet := 1024;
if GetUserNameExW(I,vPWChart, vSizet) then
begin
SetString(vWNameUser, vPWChart, vSizet-1);
vNameUser := UTF8Encode(vWNameUser);
end
else
begin
vNameUser := '';
vNameUser := 'LastError: ' + SysErrorMessageUTF8(GetLastError);
end;
Memo1.Lines.Add('GetUserNameEx '+IntToStr(I)+': '+vNameUser);
end;
FreeMem(vPWChart);
end;
Размер использованного буфера возвращаемый системными функциями GetUserNameW и GetUserNameExW больше на 1.
Добавлено спустя 46 секунд:
Sharfik - спасибо!
Теперь ты мне подскажи, сделал как у тебя через GetMem выделение памяти под String.
При передаче адреса в качестве параметра функции в самой функции он уже не читается. Адрес другой.
Чтение это присвоение адреса аналогичной переменной с адресом
Я ошибся в присвоениях или система не позволяет передать объявленный участок памяти в другую функцию?
При передаче адреса в качестве параметра функции в самой функции он уже не читается. Адрес другой.
Код: Выделить всё
....
vPString := GetMem(vSizet);
MyFunction(vPString ) // function MyFunction(Sender:Pointer):Integer;
Чтение это присвоение адреса аналогичной переменной с адресом
Код: Выделить всё
function MyFunction(Sender:Pointer):Integer;
...
vPString := Sender;
....text:=vPString^;
Я ошибся в присвоениях или система не позволяет передать объявленный участок памяти в другую функцию?
особо не вникал, но
>>сделал как у тебя через GetMem выделение памяти под String.
Выделять vPString := GetMem(vSizet); смысла нет, т.к. нужно vPString := GetMem(sizeof(string)) - выделяем память под переменную, под значение память выделит rtl, но нужно незабыть ее проинициализировать, иначе будут AV
>>При передаче адреса в качестве параметра функции в самой функции он уже не читается. Адрес другой.
ты похоже путаешь @vPString и @vPStringх[1] - для стрингов адрес переменной и адрес значения (содержимого переменной) - разные вещи
>>сделал как у тебя через GetMem выделение памяти под String.
Выделять vPString := GetMem(vSizet); смысла нет, т.к. нужно vPString := GetMem(sizeof(string)) - выделяем память под переменную, под значение память выделит rtl, но нужно незабыть ее проинициализировать, иначе будут AV
>>При передаче адреса в качестве параметра функции в самой функции он уже не читается. Адрес другой.
ты похоже путаешь @vPString и @vPStringх[1] - для стрингов адрес переменной и адрес значения (содержимого переменной) - разные вещи
vPString:PString; //PString=^String
vPString - указатель на адрес значения
@vPString - указатель на адрес переменной с указателем на значение
Передаваться должен первый. С ним по работе проблем нет, пока не читаю указатель в функции вложенной, там адрес другой получаю. Вроде всегда нормально было, а тут бред...
vPString - указатель на адрес значения
@vPString - указатель на адрес переменной с указателем на значение
Передаваться должен первый. С ним по работе проблем нет, пока не читаю указатель в функции вложенной, там адрес другой получаю. Вроде всегда нормально было, а тут бред...
vPString:PString; //PString=^String
vPString - указатель на адрес значения
@vPString - указатель на адрес переменной с указателем на значение
Что есть значение?
>>vPString - указатель на адрес значения
Указатель на переменную типа string, а указатель на само текстовое значение лежит внутри этой переменной вместе с другой служебной информацией
Код: Выделить всё
vPString:pstring;
....
vPString := GetMem(sizeof(string));
pointer(vPString):=nil;
pstring^:=text;
MyFunction1(vPString);//MyFunction1(param:pstring)
MyFunction2(vPString^);//MyFunction2(param:string)
MyFunction3(@vPString^[1]);//MyFunction3(param:pchar)должно быть чтото типа такого при динамическом создании стрингов
>>Вроде всегда нормально было, а тут бред...
попрежнему всё нормально, ищите ошибки))
Все проще, я правильно делал, только stdcall; функции которой передавал адрес не прописал. 
Для выделения памяти под динамические строки
Лучше всего применять функцию NewStr(const S: string): PString;
в паре с DisposeStr(S: PString);
То есть что задал то и освободил .И никаких лишних "танцев с бубном" вокруг длины строки ...
(Что с учетом кодировки UTF8 задача временами не тривиальная )
Лучше всего применять функцию NewStr(const S: string): PString;
в паре с DisposeStr(S: PString);
То есть что задал то и освободил .И никаких лишних "танцев с бубном" вокруг длины строки ...
(Что с учетом кодировки UTF8 задача временами не тривиальная )
