.NET Compact Framework使用P/Invoke服务 (一)

     最近需要用到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 的定义。
public class APIHelper
{
[DllImport("coredll.dll", SetLastError = true)]
public static extern int MessageBoxW(IntPtr hWnd, String text, String caption, uint type);
}

然后可以对它进行调用。
private void button1_Click(object sender, EventArgs e)
{
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 不支持回调,即无法向非托管函数传递一个委托并在非托管函数中被调用。使用需要回调的非托管函数时会引发异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值