2009-05-07 3 views

답변

10

예외를 throw해야합니다. 예외는 Framework에서 HRESULTS에 매핑되며 HRESULT는 COM 클라이언트에 오류를 반환하는 표준 방법이므로이 방법이 필요합니다.

각 예외 유형에는 HResult 속성이 있습니다. COM 클라이언트에서 호출 된 관리 코드가 예외를 throw하면 런타임에서 HResult를 COM 클라이언트로 전달합니다. 응용 프로그램 별 HRESULT 코드를 원할 경우 고유 한 사용자 정의 예외 유형을 만들고 Exception.HResult 속성을 설정할 수 있습니다.

COM 클라이언트에 예외가 발생하면 호출 스택 정보가 손실됩니다. 따라서 COM 클라이언트에 전파하기 전에 예외를 기록하는 것이 좋습니다.

가끔은 다음과 같은 기술을 사용합니다. 예외를 기록하고 예외를 다시 발생시키는 COM 클라이언트에 대해 ComVisible 인터페이스를 명시 적으로 구현하십시오. COM 클라이언트는 전파하기 전에 예외를 기록하는 ComVisible 인터페이스를 사용합니다. .NET 클라이언트는 구체적인 클래스를 사용하며 예외 처리를 위해 자체적으로 준비해야합니다. 글쓰기가 약간 길지만 나중에 문제를 해결할 때 도움이 될 수 있습니다.

이 접근법의 또 다른 장점은 COM 클라이언트의 COM 제한과 표준 .NET 클라이언트의 표준 API에 맞게 조정할 수 있다는 것입니다. 예를 들어 COM 클라이언트는 참조를 기준으로 배열을 전달하는 것으로 제한되며 .NET 클라이언트에서는 참조로 전달하는 것이 바람직하지 않습니다.

예 :

[ 
ComVisible(true), 
GuidAttribute("..."), 
Description("...") 
] 
public interface IMyComVisibleClass 
{ 
    // Text from the Description attribute will be exported to the COM type library. 

    [Description("...")] 
    MyResult MyMethod(...); 

    [Description("...")] 
    MyOtherResult MyArrayMethod([In] ref int[] ids,...); 
} 
... 
[ 
ComVisible(true), 
GuidAttribute("..."), 
ProgId("..."), 
ClassInterface(ClassInterfaceType.None), 
Description("...") 
] 
public class MyComVisibleClass : IMyComVisibleClass 
{ 
    public MyResult MyMethod(...) 
    { 
     ... implementation without exception handling ... 
    } 

    public MyOtherResult MyArrayMethod(int[] ids,...) 
    { 
     ... input parameter does not use ref keyword for .NET clients ... 
     ... implementation without exception handling ... 
    } 

    MyResult IMyComVisibleClass.MyMethod(...) 
    { 
     // intended for COM clients only 
     try 
     { 
      return this.MyMethod(...); 
     } 
     catch(Exception ex) 
     { 
      ... log exception ... 
      throw; // Optionally wrap in a custom exception type 
     } 
    } 

    MyOtherResult IMyComVisibleClass.MyArrayMethod(ref int[] ids, ...) 
    { 
     // intended for COM clients only 
     try 
     { 
      // Array is passed without ref keyword 
      return this.MyArrayMethod(ids, ...); 
     } 
     catch(Exception ex) 
     { 
      ... log exception ... 
      throw; // Optionally wrap in a custom exception type 
     } 
    } 

} 
1

그게 레거시 응용 프로그램이 반응하는 방법에 따라 다릅니다 생각합니다. 오류 반환 값을 이해하면 해당 방법으로 이동하십시오. 그렇지 않으면 예외를 던져 적절하게 처리하기를 바랍니다.

또한 나쁜 참조 (예 : null 참조) 또는 기타 심각한 오류 인 경우 예외가 발생합니다. 그러나 소비자가 미리 확인할 수없는 사항 (예 : 비어있는 검색이 예외를 발생해서는 안 됨)에 대해서는 예외를 피해야합니다.

3

C# 서비스를 호출 할 때 COM 응용 프로그램이 IErrorInfo 인터페이스를 지원하고 완전히 내부 프로젝트 인 경우 예외를 throw하는 것이 대부분의 정보를 캡처 할 때 가장 좋은 방법 일 수 있습니다. 그러나 COM은 전통적으로 HR 결과에 의존하여 상태 결과를 전달하며 서비스가 다른 출처에 게시되는 경우 더 좋을 수 있습니다.

편집 : 나는 조의 대답을 더 좋아합니다.

+0

예외가 HRESULTS에 매핑되는, 그래서 이것은 가장 좋은 방법입니다. 아래 내 답변을 참조하십시오. – Joe

1

예외 또는 반환 값 중 어느 것을 사용할지를 판단하는 가장 좋은 방법은 귀하가됩니다. "예외를 던지기"는 여러 측면에서 "가치를 반환"보다 중요합니다. 그러나 어떤 경우에는 반환 값으로 충분할 것입니다.

3

본인은 프로젝트를 자세히 알지 못하면 "예 또는 아니요"라는 대답에 동의합니다.

그것은 다음과 같은 요인에 따라 달라집니다 : (당신의 클라이언트가 예외에 대해 무엇을 알고 있어야 예)

  • 보안
  • 효율성
  • 유지 보수성 ((즉 중요한 처리 시간입니다) 즉, 당신은

Here's a good blog post that discusses a number of subtle points about exception processing.

0123) 당신의 예외 상황을 분석하기 위해 기존의 C++ 코드를 변경할 수 있습니다

저자는 권고 중 두 가지 방법 중 하나를

다음 중 하나를

  • 반환 오류 문서.

나 :

  • 로그인 서버의 예외에 대한 모든 정보를 제공합니다.
  • 기록 된 정보를 참조하는 새로운 예외를 만듭니다.
  • 클라이언트 측 처리 용 클라이언트 에 대한 새로운 예외를 으로 보내고보고합니다.

저는 개인적으로 C# 서비스와 C++ 응용 프로그램을 긴밀하게 연결하지 않도록주의해야한다고 생각합니다. 즉, 이론적으로 모든 소비자가 사용할 수 있도록 C# 서비스를 작성하십시오. 마찬가지로 C++ 코드는 C# 서비스의 내부 동작에 의존하지 않도록 작성해야하므로 예외 (또는 오류 코드)를 변경하거나 추가해도 소비자가 손상되지 않습니다.

관련 문제