我需要在PChar变量中存储变量值(总是返回一个字符串),现在我正在使用此代码
procedure VariantToPChar(v:variant; p : PChar);
Var
s : String;
begin
s:=v;
GetMem(p,Length(s)*Sizeof(Char));
StrCopy(p, PChar(s));
end;
但我想知道是否存在更好的方式
答案 0 :(得分:4)
你真的,真的要创建一个PChar吗?只要有可能,我会使用Strings,并且只有当外部库(如Windows API)需要PChar时,我才会使用它。
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));
这样做可以避免内存(de)分配,空值和Ansi / Unicode字符的问题。如果外部函数想要写入字符串,则可以在转换之前使用SetLength()
。也许文章Working with PChar可以给你一些想法。
答案 1 :(得分:2)
更新:您确实不应该这样做或使用此代码,因为您可能会鼓励人们编写泄漏的代码。人们会调用它并且无法释放内存,因为他们不知道这个函数会分配内存。
如果要在PChar大小缓冲区中存储某些内容,并且该值仍然与p关联(指针p被修改并且从过程返回时不同),则需要将参数设为a { {1}}(按引用而不是按值)参数如下:
var
我还在上面展示了处理EVariantError,我选择通过在p参数中返回nil来处理它,但你应该考虑一下你希望它如何工作,然后以某种方式处理它。
上面的代码也泄漏了很糟糕的内存,因此我将其重命名为AllocPChar。看起来您的原始代码存在很多问题,我不能推荐一个好方法来做一大堆坏事,而您选择的名称是最糟糕的选择之一。
至少Alloc这个名字给了我一个提示,所以我在想“当我完成它时我会更好地释放它”。
答案 2 :(得分:1)
我怀疑只是一个
PChar(string(v))
表达式可以解决问题。
用于存储转换后的字符串内容的内存将在此代码范围内提供(即只要引用string(v)
- 因此您可能希望使用显式string
变量以确保仍然分配了PChar
内存。