использование FpExecVPE [Решено]

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

использование FpExecVPE [Решено]

Сообщение coyot.rush » 24.04.2011 22:49:35

Сделал функцию обертку для FpExecVPE (необходимо перекрыть переменные окружения ). Снова наткнулся на те же грабли что и с execve http://www.freepascal.ru/forum/viewtopic.php?f=13&t=6909
при запуске env переменные окружения "плывут" . Хотя вывод на консоль через writeln('EnvironmentString('+inttostr(i)+')='+GetEnvironmentString(i)) нормальный
Код: Выделить всё
function RunApp(PathToBin:string): integer;
var
PParam,PEnv:PPChar;
i:integer;
ce:integer;
begin
Getmem(PParam,(Paramcount+1)*SizeOf(Pchar));
Writeln('Paramcount='+inttostr(Paramcount+1));
for i:=0 to Paramcount-1 do
begin
  PParam[i]:=Pchar(ParamStr(i));
  writeln('ParamStr('+inttostr(i)+')='+ParamStr(i));
end;
PParam[Paramcount+1]:=nil;
ce:=GetEnvironmentVariableCount;
Getmem(PEnv,(ce+1)*SizeOf(Pchar));
writeln('EnvironmentVariableCount='+inttostr(ce));
for i:=0 to ce-1 do
begin
  PEnv[i]:=Pchar(GetEnvironmentString(i));
  writeln('EnvironmentString('+inttostr(i)+')='+GetEnvironmentString(i));
end;

PParam[GetEnvironmentVariableCount+1]:=nil;

FpExecVPE(PathToBin,PParam,PEnv);
end;
Последний раз редактировалось coyot.rush 02.05.2011 20:11:34, всего редактировалось 1 раз.
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: использование FpExecVPE

Сообщение coyot.rush » 01.05.2011 23:06:56

Проблему решил, но вопрос остался почему код приведенный выше работает не корректно :?:
Вот "обходной код"
Код: Выделить всё
function RunApp(PathToBin:string): integer;
var
PParam,PEnv:PPChar;
ce,cp,i:integer;
ListOfEnv:TStringList;
ListofParam:TStringList;
begin
ListofParam:=TStringList.Create;
cp:=Paramcount;
for i:=0 to cp do
begin
  ListofParam.Add(ParamStr(i));
end;
Getmem(PParam,(cp+1)*SizeOf(Pchar));
for i:=0 to cp do
begin
  PParam[i]:=Pchar(ListofParam[i]);
end;
PParam[cp+1]:=nil;
ce:=GetEnvironmentVariableCount;
ListOfEnv:=TStringList.Create;
for i:=1 to ce-1 do
  begin
  ListOfEnv.Add(GetEnvironmentString(i));
end;
Getmem(PEnv,(ListOfEnv.Count+1)*SizeOf(Pchar));
for i:=0 to ListOfEnv.Count-1 do
begin
Penv[i]:=Pchar(ListOfEnv[i]);
end;
Penv[ListOfEnv.Count]:=nil;
Result:=FpExecVPE(PathToBin,PParam,PEnv);
ListOfEnv.Free;
ListofParam.Free;
end;
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: использование FpExecVPE

Сообщение Mr.Smart » 01.05.2011 23:18:21

В первом случае вы не выделяете память под строку.
Код: Выделить всё
PEnv[i]:=strnew(Pchar(GetEnvironmentString(i)));

только после, нужно будет отчистить память
Код: Выделить всё
StrDispose(PEnv[i])
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: использование FpExecVPE

Сообщение coyot.rush » 01.05.2011 23:27:58

Во втором я тоже память не выделяю,для penv[i] ,но всё корректно работает :?:
Про strnew не знал, я так понимаю его применяют для массивов PPChar :?:
Тогда не понятно как работает конструкция PChar(SomeString), во многих API всё работает, и нет необходимости в ручном управление памятью :?:

Добавлено спустя 10 минут 42 секунды:
Я так понимаю, что результат функции возвращающий строку не может быть использован для передачи в API ситемы так как Result fpc обнуляет. А чтобы преобразовать в pchar нужно использовать уже существующую строку (strnew-выделяет памяти на куче для строки) :roll:
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: использование FpExecVPE

Сообщение Mr.Smart » 01.05.2011 23:42:42

Совершенно верно, выделяет и копирует её туда.
Во втором случае память вы выделяется в TStringList не явно.

Добавлено спустя 1 минуту 58 секунд:
Данную функцию применяю, когда нужно выделить память под строку и скопировать её. Не обязательно к массиву Pchar (PPChar).
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: использование FpExecVPE

Сообщение coyot.rush » 02.05.2011 20:07:45

Спасибо Mr.Smart
Данную функцию применяю, когда нужно выделить память под строку и скопировать её. Не обязательно к массиву Pchar (PPChar).

Например так
Код: Выделить всё
function SomeFunction():string;
begin
Result:='C:\';
end;
....
ShellExecute(handle,nil,strnew(SomeFunction),nil,nil,SW_SHOWNORMAL);
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: использование FpExecVPE [Решено]

Сообщение Mr.Smart » 02.05.2011 20:18:54

Строку выделенную strnew необходимо освободить при помощи StrDispose!
Код: Выделить всё
var
  p: PCahr;
begin
   p:=strnew(SomeFunction);
   ShellExecute(handle,nil,p,nil,nil,SW_SHOWNORMAL);
   StrDispose(p);
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: использование FpExecVPE [Решено]

Сообщение coyot.rush » 02.05.2011 20:51:01

Строку выделенную strnew необходимо освободить при помощи StrDispose!

Вот и утечка памяти :oops:
Почему тогда работает
ShellExecute(handle,nil,Pchar(SomeFunction),nil,nil,SW_SHOWNORMAL);

Распределение строки нету :?:
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: использование FpExecVPE [Решено]

Сообщение Mr.Smart » 02.05.2011 20:52:58

Оно будет работать, почему бы ей не работать? Память просто не освобождается и всё.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: использование FpExecVPE [Решено]

Сообщение coyot.rush » 02.05.2011 21:03:37

ShellExecute(handle,nil,Pchar(SomeFunction),nil,nil,SW_SHOWNORMAL);

Оно будет работать, почему бы ей не работать? Память просто не освобождается и всё.
:shock:
И такое рекомендуют почти на всех сайтах по программированию на delphi :!: :!: :!:
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: использование FpExecVPE [Решено]

Сообщение Mr.Smart » 02.05.2011 21:06:01

Тьфу просмотрел.
В данном случае удалением строки занимается менеджер памяти.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: использование FpExecVPE [Решено]

Сообщение coyot.rush » 02.05.2011 21:30:12

В данном случае удалением строки занимается менеджер памяти

и распределением
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

Рейтинг@Mail.ru