.NET简谈互操作(五:基础知识之Dynamic平台调用)
互操作系列文章:
.NET简谈互操作(一:开篇介绍)
.NET简谈互操作(二:先睹为快)
.NET简谈互操作(三:基础知识之DllImport特性)
.NET简谈互操作(四:基础知识之Dispose非托管内存)
.NET简谈互操作(五:基础知识之Dynamic平台调用)
.NET简谈互操作(六:基础知识之提升平台调用性能)
.NET简谈互操作(七:数据封送之介绍)
我们继续.NET互操作学习。在上篇文章中我们学习了关于托管与非托管内存Dispose(释放)问题;下面我们继续学习基础知识中的Dynamic(动态)平台调用技术;
在前几篇文章中,我们都是采用按部就班的方式来调用非托管代码的,先定义非托管代码的托管定义,然后用DllImport来标识相关调用约定;这篇文章我们将介绍怎么通过动态的方式调用非托管代码;在进行讲解之前我们有必要简单的了解一下,托管代码调用非托管代码的大概的步骤或者说是相关细节吧;只有当我们脑子里有一套属于自己的理解思路时,文章才显的有价值;[王清培版权所有,转载请给出署名]
平台调用过程原理
文字使用始终没有图片的表达性强,我们还是来看图吧;
图1:
这幅图画的不是很全,但是大概能表达意思了;
当我们第一次调用非托管DLL文件的时候(穿插一下,这里就牵扯到为什么有些东西必须由操作系统来处理,为什么要有内核,就是用来处理一些我们平时不能随便动的东西,就拿LoadLibrary方法来讲,可能它就是进入了内核然后设置相关参数,帮我们保存了非托管DLL在内存的代理存根,当我们下次又进入到内核的时候,系统去检查一下,发现有过一次调用了,所以下次就去读取存根中的地址进行调用),系统会去加载非托管DLL文件到内存并设置相关数据,以便后期使用;动态调用的原理就是我们把这部分的工作自己手动来做,比如第一次调用非托管DLL肯定是要慢于后面调用的;所以在一些必要的场合下,我们真的有必要进行动态P/Invoke;
动态平台调用示例1
在托管的.NET中我们可以通过使用Win32API中的LoadLibrary方法来手动加载非托管DLL到内存来;
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern IntPtr LoadLibrary(string iplibfilenmae);
这样的操作就好比我们图1中的第一次调用过程要执行的操作;
[DllImport("Win32DLL.dll", EntryPoint = "add", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int add(int x, int y);
同样我们还是申明非托管代码的定义,我们来看全部代码;
namespace CSharp.Interop
{
/// <summary>
/// 动态平台调用,手动加载非托管DLL文件
/// </summary>
public static class DynamicPinvoke
{
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
public static extern IntPtr LoadLibrary(string iplibfilenmae);
[DllImport("Win32DLL.dll", EntryPoint = "add", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int add(int x, int y);
public static void Test()
{
string currentdirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string dllpath = Path.Combine(currentdirectory, "Win32DLL.dll");
&n
相关新闻>>
- 发表评论
-
- 最新评论 更多>>