星期二, 九月 04, 2007

Using IReflect to expose a type as IDispatch to COM

 
 

Sent to you by Hudong via Google Reader:

 
 

via MSDN Blogs by shrib on Sep 04, 2007

The CLR supports marshalling of objects that support the IReflect interface as IDispatch COM objects. Similarly, IExpando gets marshalled as IDispatchEx. Here is a sample of a managed type called ComVisibleManagedTest which is used from VBScript and used in a late-bound way. VBScript just deals with IDispatch, and under the hoods, the CLR routes the calls to the IReflect methods implemented by ComVisibleManagedTest.

IReflect.GetMethods gets called every time COM instantiates the managed type. The CLR caches the method names for the given object, and the names are then available to COM from the IDispatch interface. If COM accesses a method name that is not in the cached list, IReflect.GetMethods get called again.

The C# code should be compiled and registered as:

csc /t:library ComVisibleManagedTest.cs

regasm /codebase ComVisibleManagedTest.dll

Here is the contents of ComVisibleManagedTest.cs

using System;

using System.Reflection;

using System.Runtime.InteropServices;

using System.Globalization;

internal class Utils {

internal static Exception NotImplemented(string message) {

Console.WriteLine(message);

return new Exception(message);

}

}

public class MyMethodInfo : MethodInfo {

string _name;

public MyMethodInfo(string name)

: base() {

_name = name;

}

#region abstract overrides

// Unimplemented methods

public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { throw Utils.NotImplemented("In MyMethodInfo.ReturnTypeCustomAttributes"); } }

public override MethodInfo GetBaseDefinition() { throw Utils.NotImplemented("In MyMethodInfo.GetBaseDefinition"); }

public override MethodImplAttributes GetMethodImplementationFlags() { throw Utils.NotImplemented("In MyMethodInfo.GetMethodImplementationFlags"); }

public override RuntimeMethodHandle MethodHandle { get { throw Utils.NotImplemented("In MyMethodInfo.MethodHandle"); } }

public override MethodAttributes Attributes { get { throw Utils.NotImplemented("In MyMethodInfo.Attributes"); } }

public override Type DeclaringType { get { throw Utils.NotImplemented("In MyMethodInfo.DeclaringType"); } }

public override Type ReflectedType { get { throw Utils.NotImplemented("In MyMethodInfo.ReflectedType"); } }

public override bool IsDefined(Type a, bool b) { throw Utils.NotImplemented("In MyMethodInfo.IsDefined"); }

public override object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {

throw Utils.NotImplemented("In MyMethodInfo.Invoke");

}

// Methods that need to be implemented for the scenario to work

public override ParameterInfo[] GetParameters() { return new ParameterInfo[0]; }

public override object[] GetCustomAttributes(bool a) { return new object[0]; }

public override object[] GetCustomAttributes(Type a, bool b) { return new object[0]; }

public override string Name {

get {

Console.WriteLine("In MyMethodInfo.Name.get({0})", _name);

return _name;

}

}

没有评论:

发表评论