标题并没有完全体现问题的本质。
我有一个返回PChar的UDF函数。
function AccountDescription(sAccountId: PChar) : PChar; stdcall;这工作正常但我意识到如果找不到accountId我想返回#N / A.
我发现了CVErr(xlErrNA)并更改了Signature以返回OleVariant。 但现在我收到[错误]不兼容的类型:'OleVariant'和'PAnsiChar'。
我找不到任何关于如何解决这个问题的信息,所以我认为我对问题的理解一定不正确。
我尝试传递一个字符串,该字符串已编译但产生了“无效变体类型”的运行时错误。
完整的代码是:
function AccountDescription(sAccountId: PChar): OleVariant; stdcall; var strResult: string; strPChar : PChar; begin try strResult:= repo.GetAccount(sAccountId).Description; strPChar := strAlloc(length(strResult)+1) ; StrPCopy(strPChar, strResult) ; Result := strPChar; except Result := CVErr(xlErrNA); end; end;注意:excel是否负责销毁字符串或者是我的清理工作? 我应该创建副本还是应该返回指向现有字符串的指针。 输入后我觉得我应该返回一个指针。
更新:删除了示例中的一些不相关的代码。
现在使用:
function AccountDescription(sAccountId: PChar): OleVariant; stdcall; var strResult: string; begin try Result := PChar(repo.GetAccount(sAccountId).Description); except Result := CVErr(xlErrNA); end; end;The title doesn't quite capture the essence of the issue.
I have a UDF function that returns a PChar.
function AccountDescription(sAccountId: PChar) : PChar; stdcall;This was working fine but I realized I wanted to return #N/A if the accountId was not found.
I discovered CVErr(xlErrNA) and changed the Signature to return OleVariant. But now I am receiving [Error] Incompatible types: 'OleVariant' and 'PAnsiChar'.
I could not find any information on how to resolve this so I figure my understanding of the problem must not be correct.
I tried just passing a string which compiled but produced a runtime error of "Invalid variant type".
The full code is:
function AccountDescription(sAccountId: PChar): OleVariant; stdcall; var strResult: string; strPChar : PChar; begin try strResult:= repo.GetAccount(sAccountId).Description; strPChar := strAlloc(length(strResult)+1) ; StrPCopy(strPChar, strResult) ; Result := strPChar; except Result := CVErr(xlErrNA); end; end;Note: Is excel responsible for destroying the string or is that my cleanup? Should I be creating a copy or should I just be returning a pointer to an existing string. After typing it I feel like I should be returning a pointer.
Update: Removed some irrelevant code in the example.
Now using:
function AccountDescription(sAccountId: PChar): OleVariant; stdcall; var strResult: string; begin try Result := PChar(repo.GetAccount(sAccountId).Description); except Result := CVErr(xlErrNA); end; end;最满意答案
你不需要PChar OleVariant转换,你可以直接为OleVariant分配一个String (它将由RTL转换为BSTR ,接收器在完成后使用它将释放):
Result := repo.GetAccount(sAccountId).Description;至于报告错误,您的Delphi代码中是否有可行的CVErr()函数? 在VB中, CVErr()返回一个类型为Error的Variant (Delphi中的varError ),其中包含错误代码( xlErrNA为2042)。 Delphi有一个VarAsError()函数用于同样的目的:
Result := VarAsError(2042);You do not need the PChar cast, you can assign a String directly to an OleVariant (it will be converted by the RTL into a BSTR that the receiver will then free when done using it):
Result := repo.GetAccount(sAccountId).Description;As for reporting an error, do you have a viable CVErr() function in your Delphi code? In VB, CVErr() returns a Variant of type Error (varError in Delphi) containing an error code (xlErrNA is 2042). Delphi has a VarAsError() function for that same purpose:
Result := VarAsError(2042);更多推荐
发布评论