문제

모든 종류의 구현과 함께 COM을 통해 C# 코드를 상호 작용해야합니다.

해당 통합 사용자에게 쉽게하기 위해 IDL에 상호 작용 된 인터페이스를 포함 시켰지만 (관련 기존 DLL의 일부이지만 Coclass 또는 구현이 없음) TLBimp를 실행하여 유형 정의를 만들어 C# 코드로 가져 왔습니다.

C#을 구현하고 Windows 레지스트리 정보를 기반으로 COM 객체를 작성하고 필요한 인터페이스에 객체를 캐스팅했습니다.

그런 다음 별도 프로젝트에서 인터페이스의 C# 구현을 만들어 등록했습니다. 기본 프로그램은 테스트 COM 객체를 올바르게 생성하지만 인터페이스에 캐스팅하지 못합니다 (C# 'AS'를 사용할 때 널 객체를 가져 와서 명시 적 캐스트에 대한 잘못된 캐스트 소지를 가져옵니다).

인터페이스가 테스트 객체에서 구현 된 것으로 식별되지 않는 이유를 누군가에게 제안 할 수 있습니까?

이것은 IDL의 인터페이스 결함입니다 (2005 년 C ++에서 컴파일) :

    [
    object,
    uuid(B60C546F-EE91-48a2-A352-CFC36E613CB7),
    dual,
    nonextensible,
    helpstring("IScriptGenerator Interface"),
    pointer_default(unique)
]
interface IScriptGenerator : IDispatch{

    [helpstring("Init the Script generator")] 
        HRESULT Init();
    [helpstring("General purpose error reporting")] 
        HRESULT GetLastError([out] BSTR *Error);
};

이것은 tlbimp에 의해 c#을 위해 만든 스터브입니다.

[TypeLibType(4288)]
[Guid("B60C546F-EE91-48A2-A352-CFC36E613CB7")]
  public interface IScriptGenerator
  {
    [DispId(1610743813)]
    void GetLastError(out string Error);
    [DispId(1610743808)]
    void Init();
  }

이것은 기본 C# 코드의 일부이며, 프로로드에 의해 COM 객체를 생성하고 iscriptGenerator 인터페이스에 캐스팅합니다.

public ScriptGenerator(string GUID)
{
  Type comType = Type.GetTypeFromProgID(GUID);
  object comObj = null;
  if (comType != null)
  {
    try
    {
      comObj = Activator.CreateInstance(comType);
    }
    catch (Exception ex)
    {
      Debug.Fail("Cannot create the script generator COM object due to the following exception: " + ex, ex.Message + "\n" + ex.StackTrace);
      throw ex;
    }
  }
  else
    throw new ArgumentException("The GUID does not match a registetred COM object", "GUID");

  m_internalGenerator = comObj as IScriptGenerator;
  if (m_internalGenerator == null)
  {
    Debug.Fail("The script generator doesn't support the required interface - IScriptGenerator");
    throw new InvalidCastException("The script generator with the GUID " + GUID + " doesn't support the required interface - IScriptGenerator");
  }

}

그리고 이것은 작동중인 C# 코드 구현입니다.

  [Guid("EB46E31F-0961-4179-8A56-3895DDF2884E"),
  ProgId("ScriptGeneratorExample.ScriptGenerator"),
  ClassInterface(ClassInterfaceType.None),
  ComSourceInterfaces(typeof(SOAAPIOLELib.IScriptGeneratorCallback))]
  public class ScriptGenerator : IScriptGenerator
  {
   public void GetLastError(out string Error)
    {
      throw new NotImplementedException();
    }
    public void Init()
    {
      // nothing to do
    }
  }
도움이 되었습니까?

해결책

다시 한 번 - 제안해 주셔서 감사합니다.

나는 마침내 스스로 문제를 해결할 수있었습니다. 나는 위의 제안을 시도했지만 아무런 진전도하지 않았다. 그런 다음 '테스트'코드에서 Interop의 네임 스페이스를 변경했습니다. TLBIMP를 사용할 때 다른 인수 사용으로 인해 기본 코드의 코드마다 다릅니다. 이것은 문제를 해결했습니다.

.NET은 COM 객체를 생성하지만 실제로 .NET 객체 인 경우 COM 레이어를 우회하고 직접 통신합니다. 이 경우 QueryInterface (Interface Guid 포함)를 사용하지 않으며 C# 네임 스페이스가 다른 경우 인터페이스가 다릅니다.

이는 .NET 코드와 통합을 지원하려면 IDL을 제외하고 원래 Interop 어셈블리를 게시해야합니다.

감사합니다, Inbar

다른 팁

인터페이스에서 이것을 필요로한다고 생각합니다

[InterfaceType(ComInterfaceType.InterfaceIsDual)]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top