C# Windows DLL 동적 호출

10142 단어 windows
object obj = WinDllInvoke("Kernel32.dll", "Beep", 

             new object[] { 750, 300 }, typeof(void));





    : 

[System.Runtime.InteropServices.DllImport("kernel32")]

private static extern IntPtr LoadLibrary(string lpLibFileName);



[System.Runtime.InteropServices.DllImport("kernel32")]

private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);



[System.Runtime.InteropServices.DllImport("kernel32")]

private static extern IntPtr FreeLibrary(IntPtr hLibModule);



/// <summary>

///     Windows DLL

/// </summary>

/// <param name="fileName">Dll   </param>

/// <param name="funName">       </param>

/// <param name="objParams">    </param>

/// <param name="returnType">   </param>

/// <returns>    </returns>

private static object WinDllInvoke(string fileName, string funName, 

     object[] objParams, Type returnType)

{

    IntPtr libHandle = IntPtr.Zero;



    try

    {

        //      

        libHandle = LoadLibrary(fileName);

        if (libHandle == IntPtr.Zero)

            return null;

        IntPtr procAddres = GetProcAddress(libHandle, funName);

        if (procAddres == IntPtr.Zero)

            return null;



        //      

        Type[] paramTypes = new Type[objParams.Length];

        for (int i = 0; i < objParams.Length; ++i)

        {

            paramTypes[i] = objParams[i].GetType();

        }



        //        

        AssemblyName asembyName = new AssemblyName();

        asembyName.Name = "WinDllInvoke_Assembly";

        AssemblyBuilder asembyBuilder = 

             AppDomain.CurrentDomain.DefineDynamicAssembly(asembyName,

             AssemblyBuilderAccess.Run);

        ModuleBuilder moduleBuilder = asembyBuilder.DefineDynamicModule("WinDllInvoke");

        MethodBuilder methodBuilder = moduleBuilder.DefineGlobalMethod("InvokeFun",

             MethodAttributes.Public | MethodAttributes.Static, returnType, paramTypes);



        //     ILGenerator ,        IL 

        ILGenerator IL = methodBuilder.GetILGenerator();

        for (int j = 0; j < paramTypes.Length; ++j)

        {

            //       

            if (paramTypes[j].IsValueType)

            {

                IL.Emit(OpCodes.Ldarg, j); //By Value

            }

            else

            {

                IL.Emit(OpCodes.Ldarga, j); //By Addrsss

            }

        }



        //        

        if (IntPtr.Size == 4)

        {

            IL.Emit(OpCodes.Ldc_I4, procAddres.ToInt32());

        }

        else if (IntPtr.Size == 8)

        {

            IL.Emit(OpCodes.Ldc_I8, procAddres.ToInt64());

        }

        else

        {

            throw new PlatformNotSupportedException("    ,      !");

        }



        IL.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, returnType, paramTypes);

        IL.Emit(OpCodes.Ret); //     

        moduleBuilder.CreateGlobalFunctions();



        //        

        MethodInfo methodInfo = moduleBuilder.GetMethod("InvokeFun");



        return methodInfo.Invoke(null, objParams);//

    }

    catch { return null; }

    finally

    {

        if (libHandle != IntPtr.Zero)

            FreeLibrary(libHandle); //    

    }

}

좋은 웹페이지 즐겨찾기