WinCE6.0中托管代码如何访问物理空间

      之前整理过一篇《WinCE6.0中应用程序如何直接访问物理空间》的短文,文中介绍的方法突破了WinCE6.0系统本身的限制,使应用程序能够直接读写指定的内存地址,如访问系统显存。在WinCE中,使用托管代码编写应用程序直接访问物理空间,之前也曾简单介绍过,当时是基于VB.NET实现的,请参考《WinCE下VB.NET程序的开发》。今天再凑一篇基于C#的。

      原理之前两篇都已经讲过了,这里不再赘述。实现方法与VB.NET类似,首先用C++编写一个动态链接库,实现所需功能,并导出相应的函数。在托管代码中调用这些函数读写指定的物理空间。闲话不再多说,直接附上参考代码。

      SysApi.h代码如下:

 1 #ifndef __SYSAPI_H__
 2 #define __SYSAPI_H__
 3 
 4 #ifdef __cplusplus
 5 extern "C" {
 6 #endif
 7 
 8 #ifdef _WINDLL
 9 #ifdef SYSAPI_EXPORTS
10 #define CLASS_DECLSPEC __declspec (dllexport)
11 #else
12 #define CLASS_DECLSPEC __declspec (dllimport)
13 #endif
14 #else
15 #define CLASS_DECLSPEC
16 #endif
17 
18 typedef struct {
19     void*    pvDestMem;
20     DWORD    dwPhysAddr;
21     DWORD    dwSize;
22 } VIRTUAL_COPY_EX_DATA,*PVIRTUAL_COPY_EX_DATA;
23  
24 #define IOCTL_VIRTUAL_COPY_EX CTL_CODE (FILE_DEVICE_UNKNOWN,3333,METHOD_BUFFERED,FILE_ANY_ACCESS)
25 
26 CLASS_DECLSPEC LPVOID GetVirtual(DWORD dwPhyBaseAddress, DWORD dwSize);
27 CLASS_DECLSPEC VOID FreeVirtual(LPVOID pVirtualAddress);
28 CLASS_DECLSPEC VOID SetVirtual(LPVOID pVirtualAddress, BYTE val, DWORD dwSize);
29 
30 #ifdef __cplusplus
31 }
32 #endif
33 
34 #endif

      SysApi.cpp代码如下:

 1 // SysApi.cpp : 定义 DLL 应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <windows.h>
 6 #include <commctrl.h>
 7 #include <Pkfuncs.h>
 8 #include "SysApi.h"
 9 
10 BOOL APIENTRY DllMain( HANDLE hModule, 
11                        DWORD  ul_reason_for_call, 
12                        LPVOID lpReserved
13                      )
14 {
15     return TRUE;
16 }
17 
18 CLASS_DECLSPEC LPVOID GetVirtual(DWORD dwPhyBaseAddress, DWORD dwSize)
19 {
20      volatile LPVOID pVirtual;
21      VIRTUAL_COPY_EX_DATA vced;
22      
23      if(dwPhyBaseAddress & 0xFFF)
24      {
25          return NULL;
26      }
27 
28      vced.dwPhysAddr = dwPhyBaseAddress>>8;
29      pVirtual = VirtualAlloc(0, dwSize, MEM_RESERVE, PAGE_NOACCESS);
30      vced.pvDestMem = pVirtual;
31      vced.dwSize = dwSize;
32      KernelIoControl(IOCTL_VIRTUAL_COPY_EX, &vced, sizeof(vced), NULL, NULL, NULL);
33      
34      return pVirtual;
35 }
36 
37 CLASS_DECLSPEC VOID FreeVirtual(LPVOID pVirtualAddress)
38 {
39     VirtualFree(pVirtualAddress, 0, MEM_RELEASE);
40 }
41 
42 CLASS_DECLSPEC VOID SetVirtual(LPVOID pVirtualAddress, BYTE val, DWORD dwSize)
43 {
44     if (pVirtualAddress)
45     {
46         memset(pVirtualAddress, val, dwSize);
47     }
48 }

       C#的参考代码如下:  

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Text;
 7 using System.Windows.Forms;
 8 using System.Runtime.InteropServices; 
 9 
10 namespace SysApp2
11 {
12     public partial class Form1 : Form
13     {
14         [DllImport("SysApi.dll", CharSet = CharSet.Auto)]
15         public static extern IntPtr GetVirtual(uint PhyBaseAddress, uint Size);
16         [DllImport("SysApi.dll", CharSet = CharSet.Auto)]
17         public static extern void FreeVirtual(IntPtr pVirtualAddress);
18         [DllImport("SysApi.dll", CharSet = CharSet.Auto)]
19         public static extern void SetVirtual(IntPtr pVirtualAddress, byte val, uint dwSize);
20 
21         private IntPtr pLCDBuf;
22 
23         public Form1()
24         {
25             InitializeComponent();
26         }
27 
28         private void Black_Click(object sender, EventArgs e)
29         {
30             SetVirtual(pLCDBuf, 0x00, 0x300000);
31         }
32 
33         private void White_Click(object sender, EventArgs e)
34         {
35             SetVirtual(pLCDBuf, 0xFF, 0x300000);
36         }
37 
38         private void FormClosed(object sender, EventArgs e)
39         {
40             FreeVirtual(pLCDBuf);
41         }
42 
43         private void FormLoad(object sender, EventArgs e)
44         {
45             pLCDBuf = GetVirtual(0x4C800000, 0x300000);
46         }
47     }
48 }

       以上代码实现了,在C#编写的应用程序中通过写显存的方式将屏幕刷成全黑或者全白。示例代码的完整解决方案下载地址:http://files.cnblogs.com/we-hjb/SysApi.rar

时间: 2024-11-09 09:24:31

WinCE6.0中托管代码如何访问物理空间的相关文章

WinCE6.0中应用程序如何直接访问物理空间

   在实际开发过程中,经常希望能在应用程序中直接读写设备的物理空间.以前在做WinCE6.0下的MEMMgr时通过秘密加载一个内核态驱动实现了这个需求.但这种方式有一个明显的缺陷,每次读写都必须经由它才能完成.如果只是读取GPIO,那问题不算大.如果想通过这种方式实现视频播放的加速就比较困难了.估计非但不能加速,反而会变得更慢.      早先曾与ZL仔细的讨论过这个问题,他当时在WinCE6.0上移植TCPMP,发现播放视频不太流畅,于是想通过直接写显存进行加速.目的很明确,在应用中申请一段

体验ASP.NET 2.0 中的数据访问控件

asp.net|访问|控件|数据 简介 数据访问一直是开发 Web 应用程序的一个关键问题.几乎每个商业应用程序都需要数据驱动的 Web 页面.由于数据访问如此普遍,开发人员不断地为简单的数据库任务重新生成复杂的代码就显得毫无意义了.开发人员需要从格式各异的不同数据源中快速访问数据.幸运的是,ASP.NET 2.0 中新增的数据访问控件和 ADO.NET 2.0 解决了这一问题. 对于传统的 ASP 和 ASP.NET 1.1 应用程序而言,开发人员不得不创建代码访问和更新数据库,将检索到的数据

WinCE6.0中Romimage.exe的BUG

     WinCE6.0的Romimage.exe依然存在BUG,跟WinCE5.0一样.当新建的工程和PB的安装目录不在同一分区时就不能正确生成nb0文件.本以为WinCE6.0已经解决这个问题,不想饱汉不知饿汉饥,他们似乎没有发现这个BUG,也就不可能修复了.        好在WinCE6.0开源,在Private的目录下找到了对应的源代码目录,打算修改代码,重新编译一个romimage.exe.看了半天,没找到什么线索,貌似少一些文件.只能另辟蹊径了.        先找蛛丝马迹.在b

解决.NET2.0中对路径访问被拒绝问题

将客户网站升级到asp.net2.0后,客户说后台不能上传图片.测试了一下,出现"对路径***的访问被拒绝"的错误提示,基本上可以确定是由服务器对目录的权限控制造成的(没有写的权限).还好,现在强大的主机管理系统可以直接让我们给网站中的某个目录添加权限.如下图: 将客户网站升级到asp.net2.0后,客户说后台不能上传图片.测试了一下,出现"对路径***的访问被拒绝"的错误提示,基本上可以确定是由服务器对目录的权限控制造成的(没有写的权限).还好,现在强大的主机管

ASP.NET 2.0中的事件访问修饰符?

问题描述 我有两个问题:1.比如voidSubmit_Click(Objectsender,EventArgse)默认是不是private?我用htmlinputsubmit控件调用它时,说访问受限制,无法访问.2.asp.net中事件和方法有什么区别?方法是什么,是对象还是类,如果是类,是不是抽象类? 解决方案 解决方案二:1.是private2.事件是一种特殊的委托:方法就是方法.方法是类的组成部分.解决方案三:1.默认为private.2.类里面包含方法和事件.方法是用来调用的,事件是用来

S3C2410 &amp;&amp; WinCE6.0的中断处理分析

     S3C2410的内核是ARM920T,所以,这里先介绍一下ARM920T的异常.ARM920T中有一个当前程序状态寄存器(CPSR),其中BIT6和BIT7分别控制FIQ和IRQ的使能与否.大家经常说的开中断和关中断,就是指的设置这两个BIT.        ARM体系的异常中断如下图所示:                        可以看到,ARM920T中一共有7中异常模式,如果同一时刻有多个异常发生,系统则通过优先级顺序来决定处理其中的哪一个异常.他们之间的优先级顺序从高到低

S3C2410下WinCE6.0的启动过程详解

通过前两篇文章的介绍,我们已经知道NBOOT用来引导EBOOT,继而EBOOT加载并引导WinCE操作系统(NK).那么,WinCE6.0的启动过程又是怎样的呢?本文基于S3C2410的平台做一个详细的分析.需要说明的是,WinCE6.0的整个启动过程对于同一类型的MCU来说大同小异,如S3C2410和PXA270同属ARM平台的MCU,所以他们的启动过程是类似的,可以说唯一的不同就在OAL处,而WinCE操作系统的启动正是从OAL开始的.      OAL(OEM Adaptation Lay

WinCE6.0 KITL概要

KITL(Kernel Independent Transport Layer)即内核独立传输层,它为我们提供了一种调试WinCE的简便方法.KITL将通信服务协议和用于通信的硬件分离开来.所以我们在创建硬件传输层时就省去很多麻烦,否则我们自己必须实现与设备进行数据交互的协议.KITL工作在硬件传输层之上,因此,它无须关心用于通信的具体硬件,我们可以用USB.Serial或者Ethernet作为KITL的调试通道.具体选择哪一个,由硬件平台和软件资源决定.有些设备没有Ethernet和Seria

WinCE6.0的EBOOT概要

     为一个新的硬件设备定制WinCE6.0操作系统,一般需要完成以下几个主要步骤: 1.       针对特定的硬件设备创建板级支持包(Board Support Package缩写为BSP),BSP必须包括BOOTLOADER.OEM适配层(OEM Adaptation Layer缩写为OAL)和一些必要的驱动. 2.       利用创建的BSP,定制一个系统设计(OS Design).即通过VS2005创建一个Platform Builder的工程.该工程可编译产生最终的运行时映像文