打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C Sharp与.net学习笔记(二)

看看动态库创建与使用相关的东西

生成与使用(托管的)dll

  • dll.cs ==> dll.dll

// file: dll.cspublic class Calc{    public static int Add(int a, int b)    {        return a + b;    }}
  • main.cs ==> main.exe

// file: main.csusing System;class App{    public static void Main()    {        Console.WriteLine("{0} + {1} = {2}", 123, 456, Calc.Add(123, 456));    }}

编译:

E:\> csc /target:library dll.csE:\> csc /reference:dll.dll  main.cs

运行:

E:\> main123 + 456 = 579

动态加载dll

using System;using System.Reflection;class App{    public static void Main()    {        Assembly dll = Assembly.Load("dll");        Type calcType = dll.GetType("Calc");        object[] parameters = new object[]{123, 456};        object res = calcType.InvokeMember("Add2",                BindingFlags.Default | BindingFlags.InvokeMethod,                null,                null,                parameters);        Console.WriteLine("{0} + {1} = {2}", 123, 456, (int)res);    }}
  • 首先,加载我们动态库dll.dll,使用的Assembly.Load,也可以用(相对或绝对路径)

Assembly.LoadFrom("dll.dll");
  • 然后,获取需要的类型,存于calcType
  • 最后通过InvokeMember调用该类型中的成员函数。如果调用的不是static成员,还需要创建该类型的实例

        Object obj = Activator.CreateInstance(calcType);        object res = calcType.InvokeMember("Add",                BindingFlags.Default | BindingFlags.InvokeMethod,                null,                obj,                parameters);

另一种写法:

        MethodInfo addMethod = calcType.GetMethod("Add");        object[] parameters = new object[]{123, 456};        object obj = Activator.CreateInstance(calcType);        object res = addMethod.Invoke(obj, parameters);

使用非托管 dll

  • dll2.cpp ==> dll2.dll

// file: dll2.cppextern "C" int __declspec(dllexport) Add(int a, int b){    return a + b;}
  • main.cs ==> main.exe

// file: main.csusing System;using System.Runtime.InteropServices;class App{    [DllImport("dll2.dll")]    public static extern int Add(int a, int b);    public static void Main()    {        Console.WriteLine("{0} + {1} = {2}", 123, 456, Add(123, 456));    }}

编译运行:

E:\> cl dll2.cpp /LDE:\> csc main.csE:\> main123 + 456 = 579

这个东西被称为Platform Invoke(P/Invoke). DllImport还有一些属性

  • EntryPoint

  • CharSet

  • CallingConvention

  • SetLastError

[DllImport("dll2.dll", EntryPoint="Add", CharSet=CharSet.Auto, CallingConvention=CallingConvention.Winapi, SetLastError=true)]

动态加载dll

这又需要回到Win32 Api函数LoadLibrary、FreeLibrary这些东西了

// file: main.csusing System;using System.Runtime.InteropServices;class App{    [DllImport("kernel32.dll")]    public static extern IntPtr LoadLibrary(string dllFileName);    [DllImport("kernel32.dll")]    public static extern IntPtr GetProcAddress(IntPtr dllHandle, string functionName);    [DllImport("kernel32.dll")]    public static extern bool FreeLibrary(IntPtr dllHandle);    private delegate int AddDelegate(int a, int b);    public static void Main()    {        IntPtr handle = LoadLibrary("dll2.dll");        IntPtr pAddFunc = GetProcAddress(handle, "Add");        AddDelegate Add = (AddDelegate)Marshal.GetDelegateForFunctionPointer(                pAddFunc, typeof(AddDelegate));        Console.WriteLine("{0} + {1} = {2}", 123, 456, Add(123, 456));        FreeLibrary(handle);    }}

先用P/Invoke把这3个函数弄进来,然后用它们去处理我们要动态加载的动态库。

直接编译

E:\> csc main.cs

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
c#编写QQ群发器源码
C#模拟键盘鼠标事件 - 护马 - 博客园
C#调用DLL函数方法(下)
.NET下基于API封装的DirectUIHWND窗体访问(. NET API packa...
编程开发:内存型游戏外挂讲解
C# 简单实现QQ截图功能
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服