zoukankan      html  css  js  c++  java
  • C# 动态调用DLL

    本来是想实现控制台程序运行时自动全屏,但是只找到VC下的实现方法(http://www.vckbase.com/bbs/prime/viewprime.asp?id=347)。

    其中要使用两个未公开的Win32 API函数来存取控制台窗口,这就需要使用动态调用的方法,动态调用中使用的Windows API函数主要有三个,即:LoadlibraryGetProcAddressFreelibrary。步骤如下:

    1.   Loadlibrary: 装载指定DLL动态库

    2.   GetProcAddress获得函数的入口地址

    3.   Freelibrary: 从内存中卸载动态库

    但是C#中是没有函数指针,无法直接使用GetProcAddress返回的入口地址。后来找到资料,其实.NET 2.0新增了Marshal.GetDelegateForFunctionPointer 方法可以满足这个要求,MSDN里的解释是:将非托管函数指针转换为委托。

    后面的事就简单啦,我把它编成了一个类来方便调用。

    下面是使用的例子:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    using feiyun0112.cnblogs.com;

    namespace ConsoleApplication1
    {
        
    class Program
        
    {
            
    #region Win API
            [DllImport(
    "kernel32.dll")]
            
    public static extern IntPtr GetStdHandle(int nStdHandle);
            
    const int STD_OUTPUT_HANDLE = -11;
            
    #endregion


            
    public delegate bool SetConsoleDisplayMode(IntPtr hOut, int dwNewMode, out int lpdwOldMode);

            
    static void Main(string[] args)
            
    {
                DllInvoke dll 
    = new DllInvoke("kernel32.dll");
                
                
    int dwOldMode;

                
    //标准输出句柄
                IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                
                
    //调用Win API,设置屏幕最大化
                SetConsoleDisplayMode s = (SetConsoleDisplayMode)dll.Invoke("SetConsoleDisplayMode"typeof(SetConsoleDisplayMode));
                s(hOut, 
    1out dwOldMode);

                Console.WriteLine(
    "********************Full Screen Mode********************");
                Console.ReadLine();
               
            }

        }

    }

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;

    namespace feiyun0112.cnblogs.com
    {
        
    public class DllInvoke
        
    {

            
    #region Win API
            [DllImport(
    "kernel32.dll")]
            
    private extern static IntPtr LoadLibrary(string path);

            [DllImport(
    "kernel32.dll")]
            
    private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);

            [DllImport(
    "kernel32.dll")]
            
    private extern static bool FreeLibrary(IntPtr lib);
            
    #endregion


            
    private IntPtr hLib;        
            
    public DllInvoke(String DLLPath)
            
    {
                hLib 
    = LoadLibrary(DLLPath);
            }


            
    ~DllInvoke()
            
    {
                FreeLibrary(hLib);            
            }


            
    //将要执行的函数转换为委托
            public Delegate Invoke (string APIName,Type t)  
            
    {
                IntPtr api 
    = GetProcAddress(hLib, APIName);
                
    return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
            }


        }

    }

  • 相关阅读:
    一则由表单提交引发的思考
    前端技术栈持续汇总中(已解锁)
    5599充值中心功能开发
    CSS动画持续汇总中
    编程小技巧持续汇总中
    开发软件安装方法汇总
    HashMap中tableSizeFor
    2019年JVM面试都问了什么?快看看这22道面试题!(附答案解析)
    Spring注解@EnableWebMvc使用坑点解析
    线程池中 work 为何要实现 AbstractQueuedSynchronizer
  • 原文地址:https://www.cnblogs.com/sntetwt/p/2050937.html
Copyright © 2011-2022 走看看