玩转C++ 托管技术简介

上网baidu一下或google一下这个东东就有很多人在问这个问题,最近我也用到了这个,所以就留下来以备往后需要是可以查找。我想通过这个来作为C#调用windows APIs的出发点,在以后的随笔当中介绍一下我现阶段用到的一些APIs或非托管类库。

在调用非托管DLL的APIs前,我们应该好好掌握一下DllImportAttribute,MSDN给出的定义为:可将该属性应用于方法。DllImportAttribute 属性提供对从非托管 DLL 导出的函数进行调用所必需的信息。作为最低要求,必须提供包含入口点的 DLL 的名称。

 
 
  1.  1 using System;  
  2.  2 using System.Runtime.InteropServices;  
  3.  3 public delegate bool CallBack(int hwnd, int lParam);  
  4.  4 public class EnumReportApp {  
  5.  5 [DllImport("user32")]  
  6.  6 public static extern int EnumWindows(CallBack x, int y);  
  7.  7 public static void Main()  
  8.  8 {  
  9.  9 CallBack myCallBack = new CallBack(EnumReportApp.Report);  
  10. 10 EnumWindows(myCallBack, 0);  
  11. 11 }  
  12. 12 public static bool Report(int hwnd, int lParam) {  
  13. 13 Console.Write("窗口句柄为");  
  14. 14 Console.WriteLine(hwnd);  
  15. 15 return true;  
  16. 16 }  
  17. 17 } 

从上面的例子中我们可以看出,从Kernel32.dll中引入这个API,其中EntryPoint一看就知道是入口点,也就是DLL中的函数名称。其实只要用过VC++的人都知道,Windows APIs中都提供两个版本,一个是W,一个是A也就是Ansi和Unicode之分,现在一般都采用W,Unicode编程,但是.Net和win32交互的时候,默认是使用CharSet.Ansi来传送。在 DllImportAttribute.ExactSpelling 字段为 true 时(它是 Visual Basic .NET 中的默认值)。

平台调用将只搜索您指定的名称。例如,如果指定 MessageBox,则平台调用将搜索 MessageBox,如果它找不到完全相同的拼写则失败。当 ExactSpelling 字段为 false(它是 C++ 托管扩展和 C# 中的默认值),平台调用将首先搜索未处理的别名 (MessageBox),如果没有找到未处理的别名,则将搜索已处理的名称 (MessageBoxA)。#t#

我们可以通过创建一个代理,它带有两个参数hwnd和lparam,第一个参数是一个窗口句柄,第二个参数由应用程序定义,两个参数均为整形。当这个回调函数返回一个非零值时,标示执行成功,零则暗示失败,这个例子总是返回True值。以便持续枚举。最后创建以代理对象(delegate),并把它作为一个参数传递给EnumWindows 函数,平台会自动地 把代理对象转化成函数能够识别的回调格式。

OK,如果熟悉了以上方方面面,基本上也能够调用APIs了别忘了P/Invoke能够帮上很大的忙,我们可以去wiki网站查询我们所要的API:http://pinvoke.net。还需要说明的是很多例子等都来自MSDN和网上检索得到的!!!

THE END