calling a method using a string

Announcements and discussion for PInvoke

Moderators: Luke Jefferson, Robert

calling a method using a string

Postby barakza » Tue Aug 03, 2010 7:32 am

Hi Everybody,

I'd like to know if there's a PInvoke method I can use that will allow me to call a method by giving it's name as a string?
i.e., if I send a string "foo" , I'd like to invoke foo() function.

(I know I can use Reflection in c#, however, I'm looking for another way of solving it).

Thanks,
Barak
barakza
 
Posts: 1
Joined: Tue Aug 03, 2010 7:27 am

Postby Brian Donahue » Tue Aug 03, 2010 10:11 am

Noop, I'm afraid I only know \"the hard way\" of binding to a method. For example:
Code: Select all
            Assembly a = Assembly.Load(\"RedGate.Foo.Bar\");
            Type utilsType = a.GetType(\"x\");
            string ret = String.Empty;
            string strOut = (string)utilsType.InvokeMember(\"a\",
        BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public, new StringBinder(), utilsType, null);
            return strOut;

Note that in this case, method \"a\" has several overloads and I am interested only in the one that returns a string, so I wrote the \"StringBinder\" class:
Code: Select all
 /// <summary>
    /// This class is used to make sure an invoked member returns a String.
    /// If you do not use this binder in InvokeMethod, you will get an
    /// AmbiguousMethodException, for instance when there are two methods: W.b():boolean and W.b():String
    /// </summary>
    public class StringBinder : Binder
    {
        /// <summary>
        /// Placeholder
        /// </summary>
        /// <param name=\"bindingAttr\"></param>
        /// <param name=\"match\"></param>
        /// <param name=\"value\"></param>
        /// <param name=\"culture\"></param>
        /// <returns></returns>
        public override FieldInfo BindToField(BindingFlags bindingAttr,

            FieldInfo[] match, object value,

            CultureInfo culture)
        {

            if (match.Length > 1) throw new AmbiguousMatchException();

            return match[0];

        }
        public override MethodBase BindToMethod(BindingFlags bindingAttr,

            MethodBase[] match, ref object[] args,

            ParameterModifier[] modifiers,

            CultureInfo culture,

            string[] names, out object state)
        {

            state = null;

            foreach (MethodBase m in match)
            {
                if (m.ToString().Contains(\"String \" + m.Name)) return m;
            }
            throw new AmbiguousMatchException();
        }

        public override void ReorderArgumentArray(ref object[] args,

            object state)
        {

            //none needed

        }

        /// <summary>
        /// Placeholder
        /// </summary>
        /// <param name=\"bindingAttr\"></param>
        /// <param name=\"match\"></param>
        /// <param name=\"types\"></param>
        /// <param name=\"modifiers\"></param>
        /// <returns></returns>
        public override MethodBase SelectMethod(BindingFlags bindingAttr,

            MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
        {

            if (match.Length > 1) throw new AmbiguousMatchException();

            return match[0];

        }

        /// <summary>
        /// Placeholder
        /// </summary>
        /// <param name=\"bindingAttr\"></param>
        /// <param name=\"match\"></param>
        /// <param name=\"returnType\"></param>
        /// <param name=\"indexes\"></param>
        /// <param name=\"modifiers\"></param>
        /// <returns></returns>
        public override PropertyInfo SelectProperty(BindingFlags bindingAttr,

            PropertyInfo[] match, Type returnType, Type[] indexes,

            ParameterModifier[] modifiers)
        {

            if (match.Length > 1) throw new AmbiguousMatchException();

            return match[0];

        }

        public override object ChangeType(object value, Type type,

            CultureInfo culture)
        {

            if (value.GetType() == typeof(string))
            {

                //Console.WriteLine(\"Change '{0}' to type {1}\", value, type);

                return Convert.ChangeType(value, type);

            }

            return value;

        }



    }
Brian Donahue
 
Posts: 6670
Joined: Mon Aug 23, 2004 10:48 am


Return to PInvoke.Net

Who is online

Users browsing this forum: No registered users and 0 guests