zoukankan      html  css  js  c++  java
  • C#中动态调用DLL动态链接库

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

    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;
    
    namespace feiyun0112.cnblogs.com
    {
        public class DllInvoke
        {
    
            Win API#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);
            }
    
        }
    }

    下面是使用代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    using feiyun0112.cnblogs.com;
    
    namespace ConsoleApplication1
    {
        class Program
        {
    
            public delegate string Test(string a);
    
            static void Main(string[] args)
            {
                DllInvoke dll = new DllInvoke("test2.dll");
                Test test = (Test)dll.Invoke("testC", typeof(Test));
                string s = test("ss");
                Console.WriteLine(s);
    
                Console.WriteLine("****************************************");
                Console.ReadLine();
               
            }
        }
    }

     DllImport会按照顺序自动去寻找的地方:
    1、exe所在目录
    2、System32目录
    3、环境变量目录
    所以只需要你把引用的DLL 拷贝到这三个目录下 就可以不用写路径了

  • 相关阅读:
    js备忘录3
    js备忘录2
    js备忘录1
    Java-URLEncoder.encode 什么时候才是必须的
    Oracle中的SQL分页查询原理和方法详解
    servlet 和 threadlocal 与 web容器(理解threadlocal)
    技术汇总:第十二章:技术总览
    MongoDB :第五章:MongoDB 插入更新删除查询文档
    MongoDB :第六章:Java程序操作MongoDB
    MongoDB :第二章:系统归纳
  • 原文地址:https://www.cnblogs.com/answercard/p/5038560.html
Copyright © 2011-2022 走看看