从.NET平台调用Win32 API
2008-03-10 23:53
267 查看
Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制Windows的接口。
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool CopyFile(string src, string dst, bool failIfExists);
如何用C#语言和DllImport特性来调用Win32 API。
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static int Main()
{
MessageBox(0, "Hello Win32 API", "懒猫星空", 4);
Console.ReadLine();
return 0;
}
}
让我们剖析一下这个程序:
1. 要使用DllImport这个特性(特性也是一种类),必须使用这一句using System.Runtime.InteropServices;
,导入“运行时->交互服务”。
2. 然后我们就可以制造一个DllImport类的实例,并把这个实例绑定在我们要使用的函数上了。
3. 接下来就是我们的函数了。在C#里调用Win32函数有这么几个要点。第一:名字要与Win32 API的完全一样。第二:函数除了要有相应的DllImport类修饰外,还要声明成public static extern类型的。第三:也是最变态的一点,函数的返回值和参数类型要与Win32 API完全一致!
常用Win32数据类型与.NET平台数据类型的对应表:
Figure 2 Non-Pointer Data Types
有了这些东西,我们就能把一个Win32 API函数转成C#函数了。还拿MessageBox函数为例(看刚才给出的函数表),它的Win32原形如下:
int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
函数名:MessageBox将保持不变。
返回值:int 将保持不变(无论是Win32还是C#,int都是32位整数)
参数表:H开头意味着是Handle,一般情况下Handld都是指针类型,Win32平台的指针类型是用32位来存储的,所以在C#里正好对应一个int整型。不过,既然是指针,就没有什么正负之分,32位都应该用来保存数值——这样一来,用uint(无符号32位整型)来对应Win32的H类型更合理。不过提醒大家一点,int是受C#和.NET CLR双重支持的,而uint只受C#支持而不受.NET CLR支持,所以,本例还是老老实实地使用了int型。
至于LPCTSTR是Long Pointer to Constant String的缩写,说白了就是——字符串。所以,用C#里的string类型就对了。
修饰符:要求有相应的DllImport和public static extern
经过上面一番折腾,Win32的MessageBox函数就包装成C#可以调用的函数了:
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
第一个:弹出的MessageBox的父窗口是谁。本例中没有,所以是0,也就是“空指针”。
第二个:MessageBox的内容。本例中是“Hello Win32 API”。
第三个:MessageBox的标题。本例中用的是本人Blog的名字——水之真谛——请大家不要忘记。
第四个:MessageBox上的按钮是什么,如果是0,那就只有一个OK,MessageBox太短了,你将看不全“水之真谛”四个字,于是偶改成了4,这样就有两个按钮了。这些在MSDN的函数用法里都有。不过,我还是非常推荐您阅读一下本人的另一篇拙作《一个Win32程序的进化》 。
.NET Framework都为我们封装好了哪些Win32 API,OK,MSDN里有一篇文章,专门列出了这些。文章的名字是《Microsoft Win32 to Microsoft .NET Framework API Map》请感兴趣的朋友自己阅读。
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool CopyFile(string src, string dst, bool failIfExists);
如何用C#语言和DllImport特性来调用Win32 API。
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static int Main()
{
MessageBox(0, "Hello Win32 API", "懒猫星空", 4);
Console.ReadLine();
return 0;
}
}
让我们剖析一下这个程序:
1. 要使用DllImport这个特性(特性也是一种类),必须使用这一句using System.Runtime.InteropServices;
,导入“运行时->交互服务”。
2. 然后我们就可以制造一个DllImport类的实例,并把这个实例绑定在我们要使用的函数上了。
3. 接下来就是我们的函数了。在C#里调用Win32函数有这么几个要点。第一:名字要与Win32 API的完全一样。第二:函数除了要有相应的DllImport类修饰外,还要声明成public static extern类型的。第三:也是最变态的一点,函数的返回值和参数类型要与Win32 API完全一致!
常用Win32数据类型与.NET平台数据类型的对应表:
Figure 2 Non-Pointer Data Types
Win32 Types | Specification | CLR Type |
---|---|---|
char, INT8, SBYTE, CHAR | 8-bit signed integer | System.SByte |
short, short int, INT16, SHORT | 16-bit signed integer | System.Int16 |
int, long, long int, INT32, LONG32, BOOL, INT | 32-bit signed integer | System.Int32 |
__int64, INT64, LONGLONG | 64-bit signed integer | System.Int64 |
unsigned char, UINT8, UCHAR, BYTE | 8-bit unsigned integer | System.Byte |
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR, __wchar_t | 16-bit unsigned integer | System.UInt16 |
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT | 32-bit unsigned integer | System.UInt32 |
unsigned __int64, UINT64, DWORDLONG, ULONGLONG | 64-bit unsigned integer | System.UInt64 |
float, FLOAT | Single-precision floating point | System.Single |
double, long double, DOUBLE | Double-precision floating point | System.Double |
In Win32 this type is an integer with a specially assigned meaning; in contrast, the CLR provides a specific type devoted to this meaning. |
int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
函数名:MessageBox将保持不变。
返回值:int 将保持不变(无论是Win32还是C#,int都是32位整数)
参数表:H开头意味着是Handle,一般情况下Handld都是指针类型,Win32平台的指针类型是用32位来存储的,所以在C#里正好对应一个int整型。不过,既然是指针,就没有什么正负之分,32位都应该用来保存数值——这样一来,用uint(无符号32位整型)来对应Win32的H类型更合理。不过提醒大家一点,int是受C#和.NET CLR双重支持的,而uint只受C#支持而不受.NET CLR支持,所以,本例还是老老实实地使用了int型。
至于LPCTSTR是Long Pointer to Constant String的缩写,说白了就是——字符串。所以,用C#里的string类型就对了。
修饰符:要求有相应的DllImport和public static extern
经过上面一番折腾,Win32的MessageBox函数就包装成C#可以调用的函数了:
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
第一个:弹出的MessageBox的父窗口是谁。本例中没有,所以是0,也就是“空指针”。
第二个:MessageBox的内容。本例中是“Hello Win32 API”。
第三个:MessageBox的标题。本例中用的是本人Blog的名字——水之真谛——请大家不要忘记。
第四个:MessageBox上的按钮是什么,如果是0,那就只有一个OK,MessageBox太短了,你将看不全“水之真谛”四个字,于是偶改成了4,这样就有两个按钮了。这些在MSDN的函数用法里都有。不过,我还是非常推荐您阅读一下本人的另一篇拙作《一个Win32程序的进化》 。
.NET Framework都为我们封装好了哪些Win32 API,OK,MSDN里有一篇文章,专门列出了这些。文章的名字是《Microsoft Win32 to Microsoft .NET Framework API Map》请感兴趣的朋友自己阅读。
相关文章推荐
- 暴强贴:从.NET平台调用Win32 API
- 暴强贴:从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 暴强贴:从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 暴强贴:从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 暴强贴:从.NET平台调用Win32 API
- 转载暴强贴:从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 转载暴强贴:从.NET平台调用Win32 API
- 暴强贴:从.NET平台调用Win32 API
- .NET平台调用Win32 API
- 从.NET平台调用Win32 API
- 【.Net】从.NET平台调用Win32 API
- 从.NET平台调用Win32 API(C#调用的dll动态链接库)