Обновление: вы действительно не должны этого делать или использовать этот код , так как вы, вероятно, будете поощрять людей писать код, который пропускает. Люди будут вызывать это и не смогут освободить память, так как не знают, что эта функция выделяет память.
Если вы хотите сохранить что-то в буфере размера PChar, и это значение все еще связано с p (указатель p изменен и отличается, когда вы возвращаетесь из процедуры), тогда вам нужно сделать параметр a var
(по ссылке вместо по значению) параметр, подобный этому:
procedure AllocPCharBufFromVariant(v:variant; var p : PChar);
Var
s : String;
begin
try
s:=v;
GetMem(p,(Length(s)+1)*Sizeof(Char)); // fixed to add 1 for the nul
StrCopy(p, PChar(s));
except
on E:EVariantError do
begin
p := nil;
end;
end;
end;
Я также показал выше обработку EVariantError, которую я решил обработать, возвращая nil в параметре p, но вы должны подумать о том, как вы хотите, чтобы он работал, и затем как-то с этим справиться.
Приведенный выше код также теряет память, что ужасно, поэтому я переименовал его в AllocPChar. Кажется, в вашем исходном коде так много проблем, что я не могу рекомендовать хороший способ сделать то, что похоже на огромную кучу плохих вещей, и выбранное вами имя является одним из самых ужасных вариантов.
По крайней мере, имя Alloc подсказывает мне, поэтому я думаю: «Лучше мне освободить это, когда я закончу».