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;        www.elivn.com
        
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);
        }


    }

}

你可能感兴趣的:(dll)