开发者

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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜