您的位置:首页 > 编程语言 > C#

C#中动态调用DLL动态链接库

2015-12-11 11:54 549 查看
其中要使用两个未公开的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 拷贝到这三个目录下 就可以不用写路径了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: