组件返回S_FALSE 还是E_FAIL?

wishfly 2008-02-25 01:46:11
组件返回S_FALSE 还是E_FAIL?

当返回S_FALSE时,if(SUCCEEDED(hr)) 和try{}catch{}都不能捕获错误信息。

想知道:什么情况下使用S_FALSE?什么情况下使用E_FAIL?

另外,组件方法调用另外一个组件时,是直接返回hr,还是返回S_OK?

例如:

STDMETHODIMP CA::Call(void)
{
HRESULT hr = p->Call();
if(FAILED(hr))
return S_FALSE; 《=== 还是返回hr?

return S_OK;
}

...全文
1251 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
wishfly 2008-03-25
  • 打赏
  • 举报
回复
好像连接点是用来返回事件的,不是用来返回错误信息的。
bsl822 2008-03-14
  • 打赏
  • 举报
回复
就是增加对象的时候选择Support Connection points选项
这样就支持事件了
在事件中添加一个方法 如ShowError(BSTR strError)
然后在你的对象中添加连接点事件
这样在你的对象可以用Fire_ShowError()事件了

客户端可以写一个接收器接收抛出的错误事件了

因为我也是刚接触ATL,
所以理解不深,表达也不清楚
可参考http://www.vckbase.com/document/viewdoc/?id=1538
希望对你有所帮助

wishfly 2008-03-14
  • 打赏
  • 举报
回复
>>在组件中设置连接点抛出异常

这是怎么回事?能解释一下吗?
bsl822 2008-03-13
  • 打赏
  • 举报
回复
关键是考虑客户端进程的容错
E_FAIL会自动抛出异常,影响客户端的执行
如果你的组件出错了还不想影响客户端工做
就用return S_FALSE
在客户端用if(hr = S_OK)判断是否执行正常
在组件中设置连接点抛出异常
sjdev 2008-03-12
  • 打赏
  • 举报
回复
S_FALSE不是错误,S就是succeed缩写,返回S_FALSE目的是返回逻辑上的false.
wishfly 2008-03-12
  • 打赏
  • 举报
回复
关键--S_FALSE不是错误,是返回值。
wishfly 2008-03-12
  • 打赏
  • 举报
回复
思考的这么长时间,感觉应该是这样。

返回E_FAIL,是告诉调用程序--某些地方出错,必须进行处理。否则,程序不能进行下去了。

返回S_FALSE,不是表示出现错误。

而S_OK和S_FALSE,则程序逻辑的不同表示。如果将它们表示成S_1和S_2可能更好理解些!

调用程序只需对返回的S_OK和S_FALSE进行判断,然后决定程序的走向。

最主要的误解是由S_FALSE的名称带来的。


不知这样理解是否准确?



wishfly 2008-03-08
  • 打赏
  • 举报
回复
>>if (m_pXXX == 0)
>> return E_FAIL;
>>这样有助于你快速定位到出错代码。

对于这种情况,如果返回S_FALSE,然后在程序中判别这种情况,不是也可以吗?

比如:
if (m_pXXX == 0)
return S_FALSE;

然后在调用程序中判别这种情况

if(hr == S_FALSE){
// do something
}

仍在困惑中--什么情况下,一定得抛E_***.

wishfly 2008-03-08
  • 打赏
  • 举报
回复
>>返回e_fail时,error_handling warp class会自动抛出异常.

这我知道。
能否介绍一下你得经验---平常开发时,什么情况下S_FALSE,什么情况下E_FAIL?

最好举个例子说明--

比如:
A情况下--返回S_FALSE比较好
B情况下--返回E_FAIL比较好

不要嫌我麻烦,因为对于错误处理必须有个一致性得原则,所以比较谨慎!

谢谢了!
sjdev 2008-03-08
  • 打赏
  • 举报
回复
e不就是error的简写吗?只要是返回e_xxx的都会抛出异常。
如果你不希望使用atl产生的error_handling包装,就不要使用#import导入类型库.

什么时候抛出异常?
譬如你处理的代码中,m_pXXX正常情况下是非空的,程序中却是null.
你就可以
if (m_pXXX == 0)
return E_FAIL;
这样有助于你快速定位到出错代码。

wishfly 2008-03-08
  • 打赏
  • 举报
回复
还是那个问题:
你通常在什么情况下返回e_fail, 而不是s_false。

也就是什么情况下必须使用E_****,抛出异常?

这个问题,困扰很长时间了--因为能用E_***的地方,似乎使用S_FALSE也可以 :(
sjdev 2008-03-08
  • 打赏
  • 举报
回复
返回e_fail时,error_handling warp class会自动抛出异常.
sjdev 2008-03-07
  • 打赏
  • 举报
回复
1.使用#import指令的rename_namespace属性。
2.你说的
try{
if(nothandled(hr)){
}else{
}
}catch(_com_error &e){
}

是一种情况,不过我在程序中不需要这种判断,我需要的是:
//sometime
try{
if(succeeded(hr)){
dosth...
}
}catch(_com_error &e){
}


//sometime
try{
if(nothandled(hr)){
dosth...
}
}catch(_com_error &e){
}

当然了,自己还会定义其它一些返回值,而不仅仅局限于s_ok,s_false,e_fail等。
wishfly 2008-03-06
  • 打赏
  • 举报
回复
>>if (succeeded(hr)) // 组件进行了处理
>>if (nothandled(hr)) // 组件没有进行处理

这样作是否有点多余?

只对if (nothandled(hr)进行判断,不就可以判别S_OK和S_FALSE了吗?

比如:
try{
if(nothandled(hr){
// 处理S_FALSE
}else{
// 处理E_OK
}
}catch{
// 处理E_FAIL
}
wishfly 2008-03-06
  • 打赏
  • 举报
回复
>>import和包含相应头文件都差不多,不过我使用导入库,[out,retval]会被处理成返回值。
如果需要用到的导入库大于一个时,命名空间怎样使用。

比如:
#import "a.tlb"
using namespace alib;

#import "b.tlb"
using namespace blib;


这两个--alib和blib在使用时是否冲突?

谢谢!
sjdev 2008-03-06
  • 打赏
  • 举报
回复
我的处理方法是:
1.正确处理,返回s_ok.
2.没有处理,返回s_false.
3.进行了处理,但是处理过程中出现了错误,返回e_fail.

程序中定义
#define nothandled(status) ((hresult)(status) == s_false)

try{
if (succeeded(hr)) // 组件进行了处理
if (nothandled(hr)) // 组件没有进行处理
}catch(_com_error &e){
...
}



import和包含相应头文件都差不多,不过我使用导入库,[out,retval]会被处理成返回值。
wishfly 2008-02-28
  • 打赏
  • 举报
回复
>>还有,当遇到一般性错误(比如:某参数不在许可范围内),是返回S_FALSE还是E_FAIL?
>>----------------------
>>返回E_FAIL

还是又疑问:对于一般性错误返回E_FAIL是否有点小题大做了?

比如:

而在组件A中实现GetValue:

GetValue(long n)
{
if(n < 10 ) return E_FAIL; // E_FAIL 还是 S_FALSE ?????

return S_OK;
}


这样在调用组件时,当n>10时会抛出异常执行Netxt2(),而则会执行Next1()

try{
IAPtr->GetValue(n);
Netxt1();
}catch{
Next2();
}

这样作是否很丑陋?

其实我只是想作到以下的程序:
如果调用IAPtr->GetValue(n)时n<10,执行
Netxt1();
否则执行
Next2();
wishfly 2008-02-28
  • 打赏
  • 举报
回复
是否可以这样理解:
E_FAIL--是必须处理的返回值,否则程序出错。
而S_FALSE--则可以不处理,程序也可以正常运行。
wishfly 2008-02-28
  • 打赏
  • 举报
回复
谢谢!

还有一个问题:A组件引用B组件的一个接口, 是使用#import使用类型库,还是直接使用.h文件?
哪个效率高?

比如:

在A组件实现中

//使用#import使用类型库
#import "..\b\debug\b.tlb"
Method1()
{
try{
v = IBPtr->Value;
....
}catch{}
}

//使用.h文件
#import "..\b\b.h"
Method1()
{
pIB->get_Value(&v);
....
}

使用哪种方法好?哪种效率高?
wishfly 2008-02-28
  • 打赏
  • 举报
回复
> > 1,我返回 S_FALSE,不更改年龄,下次要获取年龄的时候,返回旧的年龄。
> > 2,返回E_FAIL,调用方处理错误。

那你选择返回S_FALSE还是E_FAIL呢?
加载更多回复(23)

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧