2

I need to make a piece of C# code interact through COM with all kinds of implementations.

To make it easeier for users of that integration, I included the interacted interfaces in IDL (as part of a relevant existing DLL, but without coclass or implementation), then got that into my C# code by running Tlbimp to create the types definition.

I implemented my C#, creating COM objects based on Windows registry info and casting the object into the interface I need.

I then created a C# implementation of the interface in a seperate project and registered it. The main program creates the testing COM object correctly but fails to cast it into the interface (gets a null object when using C# 'as', gets an InvalidCastException of explicit cast).

Can someone suggest why the interface is not identified as implemented by the testing object?

This is the interface defition in IDL (compiled in C++ in VS 2005):

    [
    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);
};

This is the stub created for C# by Tlbimp:

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

This is part of the main C# code, creating a COM object by its ProgID and casting it to the IScriptGenerator interface:

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");
  }

}

And this is the implementing C# code, to test it's working (and it's not):

  [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
    }
  }

2 Answers 2

2

Again - thanks for the suggestions.

I was able to finally resolve the issue on my own. I tried the above suggestions and didn't made any progress. Then I changed the namespace of the interop in the 'testing' code - it varied from the one in the main code because of different argument use when using Tlbimp. This solved the problem.

Here's my guess to why: .Net creates the COM object, but when it detects this is actually a .Net object, it bypass the COM layer and communicates directly. In which case, queryInterface (with the interface GUID) is not used and the interface do differ because of different C# namespaces.

This means that in order to supprot integration with .Net code, I will need to publish my original interop assembly aside the IDL.

Thanks, Inbar

Sign up to request clarification or add additional context in comments.

Comments

0

I think you need this on the interface

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.