5

すべて、戻り値の型の DLL を呼び出すために現在使用されているメソッドがありますbool。これはうまく機能します。この方法は

public static bool InvokeDLL(string strDllName, string strNameSpace, 
                             string strClassName, string strMethodName, 
                             ref object[] parameters, 
                             ref string strInformation, 
                             bool bWarnings = false)
{
    try
    {
        // Check if user has access to requested .dll.
        if (!File.Exists(Path.GetFullPath(strDllName)))
        {
            strInformation = String.Format("Cannot locate file '{0}'!",
                                           Path.GetFullPath(strDllName));
            return false;
        }
        else
        {
            // Execute the method from the requested .dll using reflection.
            Assembly DLL = Assembly.LoadFrom(Path.GetFullPath(strDllName));
            Type classType = DLL.GetType(String.Format("{0}.{1}", 
                                         strNameSpace, strClassName));
            if (classType != null)
            {
                object classInstance = Activator.CreateInstance(classType);
                MethodInfo methodInfo = classType.GetMethod(strMethodName);
                if (methodInfo != null)
                {
                    object result = null;
                    result = methodInfo.Invoke(classInstance, new object[] { parameters });
                    return Convert.ToBoolean(result);
                }
            }

            // Invocation failed fatally.
            strInformation = String.Format("Could not invoke the requested DLL '{0}'! " + 
                                           "Please insure that you have specified the namespace, class name " +
                                           "method and respective parameters correctly!",
                                           Path.GetFullPath(strDllName));
            return false;

        }
    }
    catch (Exception eX)
    {
        strInformation = String.Format("DLL Error: {0}!", eX.Message);
        if (bWarnings)
            Utils.ErrMsg(eX.Message);
        return false;
    }
}

ここで、このメソッドを拡張して、任意のタイプの DLL から戻り値を取得できるようにします。私はジェネリックを使用してこれを行うことを計画していましたが、すぐに未知の領域に入りました。コンパイル時に不明な場合に T を返すにはどうすればよいですか。リフレクションを調べましたが、この場合にどのように使用されるかわかりません。上記のコードで最初のチェックを行います

public static T InvokeDLL<T>(string strDllName, string strNameSpace, 
                             string strClassName, string strMethodName, 
                             ref object[] parameters, ref string strInformation, 
                             bool bWarnings = false)
{
    try
    {
        // Check if user has access to requested .dll.
        if (!File.Exists(Path.GetFullPath(strDllName)))
        {
            strInformation = String.Format("Cannot locate file '{0}'!",
                                           Path.GetFullPath(strDllName));
            return "WHAT/HOW??";
        ...

どうすれば欲しいものを達成できますか、それともメソッドをオーバーロードするだけですか?

どうもありがとうございました。

4

3 に答える 3

6

交換

return false;

return default(T);

return Convert.ToBoolean(result);

return (T)result;
于 2012-06-22T14:26:15.040 に答える
4

DLL から実際の値を取得していない場合は、明らかにどこかから値を作成する必要があります。考えられるすべての型に対して機能する唯一の方法Treturn default(T)、その型のデフォルト値が何であれ (つまり、任意の参照型に対して) 与える0ことですintnull

型パラメーターに型制約を設定すると、より多くのオプションを取得できますが、汎用性が犠牲になります。

于 2012-06-22T14:26:26.050 に答える
2

私はこのようなことをします:

    public static InvokeDLLResult<T> InvokeDLL<T>(string strDllName, string strNameSpace,
                         string strClassName, string strMethodName,
                         ref object[] parameters,
                         ref string strInformation,
                         bool bWarnings = false)
    {
        try
        {
            // Check if user has access to requested .dll.
            if (!File.Exists(Path.GetFullPath(strDllName)))
            {
                strInformation = String.Format("Cannot locate file '{0}'!",
                                                         Path.GetFullPath(strDllName));
                return InvokeDLLResult<T>.Failure;
            }
            else
            {
                // Execute the method from the requested .dll using reflection.
                Assembly DLL = Assembly.LoadFrom(Path.GetFullPath(strDllName));
                Type classType = DLL.GetType(String.Format("{0}.{1}", strNameSpace, strClassName));
                if (classType != null)
                {
                    object classInstance = Activator.CreateInstance(classType);
                    MethodInfo methodInfo = classType.GetMethod(strMethodName);
                    if (methodInfo != null)
                    {
                        object result = null;
                        result = methodInfo.Invoke(classInstance, new object[] { parameters });
                        return new InvokeDLLResult<T>(true, (T) Convert.ChangeType(result, methodInfo.ReturnType));
                    }
                }

                // Invocation failed fatally.
                strInformation = String.Format("Could not invoke the requested DLL '{0}'! " +
                                                         "Please insure that you have specified the namespace, class name " +
                                                         "method and respective parameters correctly!",
                                                         Path.GetFullPath(strDllName));
                return InvokeDLLResult<T>.Failure;

            }
        }
        catch (Exception eX)
        {
            strInformation = String.Format("DLL Error: {0}!", eX.Message);
            if (bWarnings)
                Debug.WriteLine(eX.Message);
            return InvokeDLLResult<T>.Failure;
        }
    }

    public class InvokeDLLResult<T>
    {
        public InvokeDLLResult(bool success, T result)
        {
            Success = success;
            Result = result;
        }

        public bool Success { get; private set; }
        public T Result { get; private set; }

        public static InvokeDLLResult<T> Failure = new InvokeDLLResult<T>(false, default(T));
    }

または、out パラメーターを使用して結果を返す TryInvokeDLL メソッドを記述します。

于 2012-06-22T14:48:45.327 に答える