How can I modify and return a variable of type PChar in a function call
I need store a v开发者_开发问答ariant value (which always return a string) in a PChar variable now i'm using this code
procedure VariantToPChar(v:variant; p : PChar);
Var
s : String;
begin
s:=v;
GetMem(p,Length(s)*Sizeof(Char));
StrCopy(p, PChar(s));
end;
But i'm wondering if exist a better way
Do you really, really have to create a PChar? As long as possible i would use Strings, and only if an external library (like the Windows API) requires a PChar, i would cast it.
uses
Variants;
var
vText: Variant;
sText: String;
begin
vText := 'Hello world';
// VarToStr() can handle also null values
sText := VarToStr(vText);
// If absolutely necessary, cast it to PChar()
CallToExternalFunction(PChar(sText));
Doing it like this you can avoid problems with memory (de)allocation, null values, and Ansi/Unicode chars. If the external function wants to write into the string, you can use SetLength()
before casting. Maybe the article Working with PChar could give you some ideas.
Update: You really shouldn't do this or use this code as you're likely to encourage people to write code that leaks. People will call this and fail to free the memory since they don't know that this function allocates memory.
If you want to store something in a PChar size buffer, and have that value still be associated with p (the pointer p is modified and is different when you return from the procedure), then you need to make the parameter a var
(by-reference instead of by-value) parameter like this:
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;
I have also shown above handling EVariantError, which I have chosen to handle by returning nil in the p parameter, but you should think about how you want it to work, and then deal with it somehow.
The above code also leaks memory which is awful, so I renamed it AllocPChar. It seems like your original code has so many problems that I can't recommend a good way to do what looks like a giant pile of bad things and the name you chose is among the most awful choices.
At least the name Alloc gives me a hint so I'm thinking "I better free this when I'm done with it".
I suspect just a
PChar(string(v))
expression will do the trick.
And the memory used to store the converted string content will be available in the scope of this code (i.e. as long as the string(v)
will be referenced - so you may want to use an explicit string
variable to ensure that your PChar
memory is still allocated).
精彩评论