Delphi 为什么导入的类型库函数与原始源不同?

Delphi 为什么导入的类型库函数与原始源不同?,delphi,delphi-xe2,Delphi,Delphi Xe2,我正在尝试使用带有COM接口的第三方库。 提供了一个C++示例应用程序,它使用声明为:的函数 HRESULT __stdcall IMyInterface::DoSomething (BSTR id, long State) 导入类型库后,生成的Delphi代码为: procedure DoSomething (const id: WideString; State: Integer); safecall; 在C++示例应用程序中,使用结果(HESRead)来确定函数是否正确执行。 为什么D

我正在尝试使用带有COM接口的第三方库。 提供了一个C++示例应用程序,它使用声明为:

的函数
HRESULT __stdcall IMyInterface::DoSomething (BSTR id, long State)
导入类型库后,生成的Delphi代码为:

procedure DoSomething (const id: WideString; State: Integer); safecall;

在C++示例应用程序中,使用结果(HESRead)来确定函数是否正确执行。 为什么Delphi将此声明转换为过程,这样我就无法返回结果了?


如何解决此问题?

安全调用调用约定只是对
HResult
返回类型的转换。如果函数返回不成功(通常不是
S_OK
S_False
),它将被包装成异常并抛出(如果SysUtils未在任何地方使用,则会变成
reseafecallerror
运行时错误)。查看
系统。\u检查自动结果
了解详细信息

同样,如果您正在实现safecall函数,任何异常都会被捕获并转换为
HResult
值(
E_Unexpected
,除非
TObject.SafeCallException
被覆盖以返回其他内容)。请参阅
System.\u HandleAutoException
了解其工作原理

如果需要,欢迎您将该过程转换回返回
HResult
的函数。这种情况下的调用约定应该是
stdcall
。以您的例子:

function DoSomething(const id: WideString; State: Integer): HResult; stdcall;

有时我发现Delphi生成的tlb是错误的。我最终手动编辑生成的tlb文件。尝试将过程更改为函数,看看它是否工作。您不需要检查它,当结果的高位被设置时,Delphi会抛出一个异常,这就是为什么该过程被声明为“safecall”。请参阅并回答它。仔细想想,尝试在命令提示符下使用-Pt-option(-Pt-Map HRESULT to safecall)在所有接口(-T)上运行tlibimp。