Delphi 无法在HResult中返回S_FALSE

Delphi 无法在HResult中返回S_FALSE,delphi,Delphi,在我的几个COM对象中,函数的HResult可以是S_OK或S_FALSE,但当我尝试在客户端应用程序中调用这些函数时,我总是得到S_OK=0,而从不得到S_FALSE=1。 例如,在ENumVariant中,如果我写入 result:=S_False 在服务器代码中,如果我在客户端代码中测试HResult,我总是得到0 S\u OK 我使用XE8。我做了一个MCVE。 服务器的代码如下所示: 客户的代码如下: 有了Reset函数中的WriteToTrace,我可以看到调用了Reset。在测

在我的几个COM对象中,函数的HResult可以是S_OK或S_FALSE,但当我尝试在客户端应用程序中调用这些函数时,我总是得到S_OK=0,而从不得到S_FALSE=1。 例如,在ENumVariant中,如果我写入

result:=S_False
在服务器代码中,如果我在客户端代码中测试HResult,我总是得到0 S\u OK

我使用XE8。我做了一个MCVE。 服务器的代码如下所示: 客户的代码如下:


有了Reset函数中的WriteToTrace,我可以看到调用了Reset。在测试程序中,返回值始终为=0。如果我在强制结果为:=s_FALSE的地方调用Next或Clone也是一样的。

我找到的唯一解决方案是导入类型库并使用早期绑定

我发布我的发现,希望有人能给出更好的解决方案

我验证了OP的描述。我可以把这个问题复述如下。我使用向导创建了一个自动化对象,并在类型库编辑器中将祖先从IDispath更改为IEnumVARIANT。对于IEnumVARIANT的实现,我只为每个HRESULT添加了S_FALSE

当与导入类型库的应用程序一起使用时,我会得到预期的S_FALSE,但一旦使用CreateOLEObject,每次都会得到S_OK


以下是我认为会发生的事情。IEnumVARIANT具有stdcall的调用约定,这是正确的,它们只返回HResult。但是,当通过调度接口调用它们时,结果会丢失,并且总是返回S_OK。我想知道stdcall是否作为safecall隐式地重新装箱,但是再次。。。我们得到了结果,所以我放弃了这个想法

这似乎是不对的,当然,如果您为结果分配了某些内容,它应该会返回该结果。你能展示一下这个函数的全部内容以及你如何调用它,它总是返回S_OK吗?听起来问题可能是呼叫约定不匹配。另外,您使用的是哪个Delphi版本?在COM的两边?这是胡说八道。在除两种情况外的所有情况下,您发布的代码行都将返回S_FALSE:1函数从未调用,这意味着代码行从未执行;2代码行执行后,代码中的某些内容正在改变结果。脱离上下文的一行代码毫无意义。显示一个实际的、可编译的应用程序,其中包含该行代码的函数,以及在不返回S_FALSE的情况下调用该函数的代码。当我说可编译时,我指的是我们可以从你的问题中复制、编译和运行的代码。大量COM控件从Delphi代码返回S_FALSE。可能是您在某个地方有一个旧的.dcu可访问,而它被使用了吗?更改WriteToTrace的文本以确保,例如WriteToTrace“这是一个新版本”;新文本是写的,而不是旧文本。如果旧文本仍然出现,则表示您没有调用所编辑的代码。在我身上发生过几次,这可能会让我非常沮丧。这是一个真正的问题。我可以用一个简单的自动化对象和基于IEnumVARIANT的接口重现这个问题。如果我使用CreateOLEObject,我总是得到0 S_OK。如果我对导入的类型库使用早期绑定,我会得到1个S_FAIL或任何我作为HResult预期通过的结果。好吧,我不是疯了!!贾斯珀,你能再解释一下你做了什么吗?谢谢这太奇怪了!!我尝试过安全呼叫,但问题仍然存在。也许Delphi并不是编写和使用COM对象的最佳语言:-@michastro我认为您无法更改调用约定,因为它是在IEnumVARIANT中定义的。请注意,您的样本不是最小的,也不是很容易验证的,当您这样做时,您将得到否决票和许多不可信的答复