Tuesday, August 21, 2007

COM interface and .NET interoperability



VC++ COM interface in a DLL :

-------------------------------

interface IModuleConfig

{

HRESULT SetValue(

const GUID* pParamID, VARIANT* pValue);

};

DLL component Id is

9C9A2859-C76B-4205-A52A-3ADBA54458B7.

DLL component implements this interface...

 

C# code :

I created the instance for the DLL component as follows :

[

ComImport, Guid ("9C9A2859-C76B-4205-A52A-3ADBA54458B7")]

public class DLLComponent

{

}

 

This is like defining the CLSID in VC++...

 

How to create an instance for the specified Guid ?

 

Type t = typeof(DLLComponent);

DLLComponent dllComponent;

dllComponent = Activator.CreateInstance(t);

 

 

How to Query the interface from the DLL component Instance ?

IModuleConfig config = null;

config = dllComponent as IModuleConfig;

or

config = (IModuleConfig) dllComponent;

But we have to declare the IModuleConfig interface in the C# as follows ;

[

ComImport, System.Security.SuppressUnmanagedCodeSecurity ,

Guid("486F726E-4D43-49b9-8A0C-C22A2B0524E8" ),

InterfaceType(ComInterfaceType .InterfaceIsIUnknown)]

public interface IModuleConfig

{

[PreserveSig]

int SetValue([In , MarshalAs(UnmanagedType .LPStruct)]Guid guid, ref Object obj);

}

Afterwards we can call the interface method using its object with dot operator...

IModuleConfig config = null;

config = dllComponent as IModuleConfig;

config.SetValue(guid, ref obj);

 

Now it is working well.

Wrong code:

==============

Previously I defined the C# interface as follows :

[

ComImport, System.Security.SuppressUnmanagedCodeSecurity ,

Guid("486F726E-4D43-49b9-8A0C-C22A2B0524E8" ),

InterfaceType(ComInterfaceType .InterfaceIsIUnknown)]

public interface IModuleConfig

{

[PreserveSig]

int SetValue([In , MarshalAs(UnmanagedType .LPStruct)]Guid guid,[In , MarshalAs(UnmanagedType .AsAny) ref Object obj);

}

I got the exception as follows, we can't use the "UnmanagedType

.AsAny" ref types and Array with offset parameters.

  I thank verymuch to muthu pandi anna for helping me to solve this problem.

 
For VARIANT* we have to use the ref type.

 

2 comments:

Steve said...

Hi Sundar,

I've been trying to get the IModuleConfig interface working in C# for the past week! I just stumbled across your blog post and it looks like you have it working? I'm trying to use this interface in C# to set parameters on some DirectShow filters.

I would be truly greatful if you could send me your complete C# IModuleConfig code? (stephen DOT larkin AT gmail DOT com)

Kind Regards,
Steve

Federico said...

Hello Sundar,
i already wrote you on elecard forum.

I would be also greatful if you could help me get IModuleConfig working in c# ad i always have a E_NOINTERFACE error when applyed on IBaseFilter.
(my email is freddyk AT ifrance DOT com)

Thanks in Advance
Freddy