导读:
最近需要用到Wince底层编程的一些东西,在PPC中用到进程,但是.NET Compact Framework不支持process组件,上网查到这些东西,以前可从来没有接触过底层的东西,觉得比较好,拿出来大家一起看!
一、P/Invoke
在.NET Compact Framework的支持下,可以方便高效地开发出适合于移动设备的应用程序,而不需要去考虑特定的硬件环境。.NET Compact Framework向开发者屏蔽了硬件底层的细节,使开发者可以集中精力于业务逻辑的解决方案。
作为.NET Framework 的一个子集,.NET Compact Framework只提供了.NET Framework的一部分功能,因此有时在实现一些功能时不得不借助于Windows CE API。另外还存在一些第三方的组件/资源,或以动态链接库形式提供,或者已经是COM组件。相对于.NET Compact Framework,它们都属于非托管资源。我们需要一种功能,实现由托管环境访问这些非托管资源。和.NET Framework 一样,平台调用P/Invoke(Platform Invocation Services)提供托管代码调用驻留于DLL 中的非托管函数的功能。下面是一张P/Invoke原理图,来自MSDN。
归纳起来,使用P/Invoke的场合包括:
1、.NET Compact Framework没有实现某功能,需要借助Windows CE API;
2、已有DLL或COM组件等资源,希望能充分利用,减少开发成本和风险;
3、鉴于DLL的执行性能和反编译能力都可能高于.NET Compact Framework,借助DLL提高程序性能和安全性。当然关于DLL的执行性能是否高于托管代码,不能一概而论。
二、.NET Compact Framework下的P/Invoke
先看一个P/Invoke的例子。下面使用DllImport特征导入Windows CE的API函数MessageBoxW的定义。
publicclassAPIHelper
{
[DllImport("coredll.dll", SetLastError= true)]
publicstaticexternintMessageBoxW(IntPtrhWnd, Stringtext, Stringcaption, uinttype);
}
然后可以对它进行调用。
privatevoidbutton1_Click(objectsender, EventArgse)
{
APIHelper.MessageBoxW(IntPtr.Zero, "测试MessageBoxW函数",
"api调用", 0);
}
可以看到,使用P/Invoke包括 声明和 调用两个过程,另外还有一个 错误处理的过程。通过声明来指定要调用的非托管函数,.NET Compact Framework也是使用DllImport特性来进行声明,包括模块名、函数名及调用约定。与.NET Framework完整版的DllImport特性不同,.NET Compact Framework的一共包括五个公共字段:CallingConvention,CharSet,EntryPoint,PreserveSig和SetLastError。具体各字段的说明可以参考MSDN。
EntryPoint可以指定为函数名或函数的序号值,如EntryPoint = "MessageBoxW"或EntryPoint = "#858"。值得注意的是.NET Compact Framework 下CallingConvention只支持CallingConvention.Winapi,即默认的平台调用;编码方式只支持Unicode,因此CharSet实际只有CharSet.Unicode一个取值。因此在导入定义时省略CallingConvention和CharSet字段的效果没有分别。
另外,DllImport修饰的方法必须用static 和extern 关键字来指明方法是在外部实现的,对其可见性修饰符则没有限制。
调用DllImport导入的非托管函数时,CLR的P/Invoke服务从声明中提取出元数据,定位要调用的模块(coredll.dll),将其加载到内存,然后根据入口点信息检索非托管函数地址。如果不出现错误,则P/Invoke完成参数的封送并调用该函数,并把返回函数的返回值。
P/Invoke会产生两种错误,一种是上面说到的P/Invoke在定位调用模块,检索函数地址时出错。如P/Invoke找不到入口点时会出错,并抛出MissingMethodException异常;函数的调用约定声明有误时会抛出NotSupportedException异常,这时应检查函数的参数及返回值定义是否与模块中函数吻合。P/Invoke的另一种错误是执行非托管函数过程中发生的错误。
另一个需要特别注意的是,.NET Compact Framework下P/Invoke不支持回调,即无法向非托管函数传递一个委托并在非托管函数中被调用。使用需要回调的非托管函数时会引发异常。
本文转自
http://hi.baidu.com/xiaotown/blog/item/cae7099b67a787b7c8eaf417.html
最近需要用到Wince底层编程的一些东西,在PPC中用到进程,但是.NET Compact Framework不支持process组件,上网查到这些东西,以前可从来没有接触过底层的东西,觉得比较好,拿出来大家一起看!
一、P/Invoke
在.NET Compact Framework的支持下,可以方便高效地开发出适合于移动设备的应用程序,而不需要去考虑特定的硬件环境。.NET Compact Framework向开发者屏蔽了硬件底层的细节,使开发者可以集中精力于业务逻辑的解决方案。
作为.NET Framework 的一个子集,.NET Compact Framework只提供了.NET Framework的一部分功能,因此有时在实现一些功能时不得不借助于Windows CE API。另外还存在一些第三方的组件/资源,或以动态链接库形式提供,或者已经是COM组件。相对于.NET Compact Framework,它们都属于非托管资源。我们需要一种功能,实现由托管环境访问这些非托管资源。和.NET Framework 一样,平台调用P/Invoke(Platform Invocation Services)提供托管代码调用驻留于DLL 中的非托管函数的功能。下面是一张P/Invoke原理图,来自MSDN。

归纳起来,使用P/Invoke的场合包括:
1、.NET Compact Framework没有实现某功能,需要借助Windows CE API;
2、已有DLL或COM组件等资源,希望能充分利用,减少开发成本和风险;
3、鉴于DLL的执行性能和反编译能力都可能高于.NET Compact Framework,借助DLL提高程序性能和安全性。当然关于DLL的执行性能是否高于托管代码,不能一概而论。
二、.NET Compact Framework下的P/Invoke
先看一个P/Invoke的例子。下面使用DllImport特征导入Windows CE的API函数MessageBoxW的定义。
publicclassAPIHelper
{
[DllImport("coredll.dll", SetLastError= true)]
publicstaticexternintMessageBoxW(IntPtrhWnd, Stringtext, Stringcaption, uinttype);
}
然后可以对它进行调用。
privatevoidbutton1_Click(objectsender, EventArgse)
{
APIHelper.MessageBoxW(IntPtr.Zero, "测试MessageBoxW函数",
"api调用", 0);
}
可以看到,使用P/Invoke包括 声明和 调用两个过程,另外还有一个 错误处理的过程。通过声明来指定要调用的非托管函数,.NET Compact Framework也是使用DllImport特性来进行声明,包括模块名、函数名及调用约定。与.NET Framework完整版的DllImport特性不同,.NET Compact Framework的一共包括五个公共字段:CallingConvention,CharSet,EntryPoint,PreserveSig和SetLastError。具体各字段的说明可以参考MSDN。
EntryPoint可以指定为函数名或函数的序号值,如EntryPoint = "MessageBoxW"或EntryPoint = "#858"。值得注意的是.NET Compact Framework 下CallingConvention只支持CallingConvention.Winapi,即默认的平台调用;编码方式只支持Unicode,因此CharSet实际只有CharSet.Unicode一个取值。因此在导入定义时省略CallingConvention和CharSet字段的效果没有分别。
另外,DllImport修饰的方法必须用static 和extern 关键字来指明方法是在外部实现的,对其可见性修饰符则没有限制。
调用DllImport导入的非托管函数时,CLR的P/Invoke服务从声明中提取出元数据,定位要调用的模块(coredll.dll),将其加载到内存,然后根据入口点信息检索非托管函数地址。如果不出现错误,则P/Invoke完成参数的封送并调用该函数,并把返回函数的返回值。
P/Invoke会产生两种错误,一种是上面说到的P/Invoke在定位调用模块,检索函数地址时出错。如P/Invoke找不到入口点时会出错,并抛出MissingMethodException异常;函数的调用约定声明有误时会抛出NotSupportedException异常,这时应检查函数的参数及返回值定义是否与模块中函数吻合。P/Invoke的另一种错误是执行非托管函数过程中发生的错误。
另一个需要特别注意的是,.NET Compact Framework下P/Invoke不支持回调,即无法向非托管函数传递一个委托并在非托管函数中被调用。使用需要回调的非托管函数时会引发异常。
本文转自
http://hi.baidu.com/xiaotown/blog/item/cae7099b67a787b7c8eaf417.html