`
donsun
  • 浏览: 31718 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

DotNet托管C# VS DotNet托管C# 调用C++本地代码

阅读更多

DotNet托管C# VS DotNet托管C# 调用C++本地代码



1    概要    2
2    开发环境    2
3    名词解释    2
4    方案定义    3
4.1    什么是C#托管代码    3
4.2    什么是C++本地代码    3
4.3    C#托管代码如何调用C++本地代码    3
5    方案比较    4
5.1    Mobile系统瓶颈分析    4
5.2    C#托管代码与C#调用C++本地代码的比较    5
5.3    方案选择    6
5.4    实施过程中的特殊情况    6
6    总结    6
7    参考资料    7

 

1    概要

在Mobile项目中,开发模式的选择对于系统的性能与灵活性起着至关重要的作用,如何在C#托管代码与C#托管代码调用C++本地代码之间做出选择,取决于性能与灵活性的权衡。
备选方案:

  • 纯C#托管代码
  • C#托管代码通过P/Invoke调用C++本地代码

本文将从Mobile项目开发的各个方面讨论两个方案的可行性,最终将推荐采纳其中之一的解决方案使用于Mobile 2中。

2    开发环境

定义开发环境,有利于在基础层面确定可行性方案的支撑平台。

项目 属性 备注
硬件平台 SC32442/PXA270/XScale/TI OMAP 730/750/850等
软件平台 Windows Mobile 5.0 Windows Mobile 2003
开发工具    Visual Studio 2005
开发语言    Visual C# &Visual C++       
移动数据库 SQL Server CE 2003   
.Net Compact framework
    2.0/1.1

 

3    名词解释

  • 托管代码(Managed Code)

所谓托管代码即为中间代码(Middle Language),而非原生可执行代码,不能被处理器直接使用,需要虚拟机与相对庞大的运行时环境(RTE)支持,执行效率偏低,但更灵活且具有更好可移植特性。

  • 本地代码(Native Code)

本地代码指针对特定的操作系统,特定的处理器指令集编译连接的特定的机器指令,无法跨平台移植,也无足够的灵活性,但具有非常高的执行效率。

4    方案定义

首先解释一下C#托管代码与C++本地代码的区别。

4.1    什么是C#托管代码

C#托管代码,Microsoft.Net Compact framework 平台上执行的中间语言编码(Middle Language),由于.Net Compact framework 运行于资源相对匮乏的移动平台,平台的开发商在中间代码的执行效率上作了优化,包括削减运行时库(RTL),即时编译机制(JIT),缩短内存自动回收(GC)周期等方法优化中间码性能,使其性能相对PC平台的.Net Framework有了很大的改善,但是对于移动平台来说其性能还是远远达不到本地代码效率。但其优势也是显而易见的,.Net Compact framework强大支撑平台,丰富的界面元素支持,Windows Mobile的跨平台特性等是本地程序无法比拟的,并且托管代码的开发与集成开发环境(IDE)的完美结合使得快速开发的成为可能。

4.2    什么是C++本地代码

C++本地代码,本地代码(Native)是相对于中间代码(Middle Language)而言的,本地代码指基于特定的处理器指令集编译的,可以直接在硬件平台上执行的原生代码。由于移动平台的资源有限,处理器能力与内存资源的受限,所以Window Mobile 2003之前的的版本是不支持.Net Compact framework运行时环境的,这也是出于运行效率的考虑,毕竟中间代码需要解释器与运行时编译器支持,并且需要一个相对来说比较消耗资源的运行时环境支持,包括垃圾收集器(GC)等。
所有版本的Windows Mobile操作系统都支持本地代码的执行,但对于不同的操作系统与硬件环境,需要编译不同的可执行程序,以使其可以运行于不同的平台上,给软件组件化跨平台部署带来了很大的不便,但本地代码的优势也是显而易见的,本地代码直接运行于硬件平台之上,采用C++编译器其性能是最优的,在Windows Mobile系统中,编写高效率的处理程序,硬件驱动程序或者要求高性能的算法,使用C++本地代码为首选方案。

4.3    C#托管代码如何调用C++本地代码

在一些特殊的环境中,以C#托管代码为主要的开发结构的系统中,有时会有一整块的功能需要高性能处理,例如图形渲染,高精度数值计算等,这就可以采用C#托管代码调用C++本地编写的Dll来实现该需求,.Net Compact framework提供了P/Invoke方式从托管代码中调用非托管的本地Dll,可以很好的解决这个问题,但是Micorsoft表示P/Invoke的性能并不是很好,远远达不到本地代码调用本地代码Dll的性能,所谓P/Invoke的性能不好并非是本地代码的执行效率问题,P/Invoke不会影响到非托管代码的执行,只是调用过程中的开销比较大,也就是说高密度频繁调用小量的高效率代码的代价可能会超过纯粹的托管代码,其效率损耗主要在托管类型与本地类型的相互转换上,以及非托管Dll的加载与释放上,所以使用P/Invoke非常适合足够规模一整块的高效率代码调用,而非频繁的小规模调用,小规模高密度频繁的P/Invoke调用往往在性能上得不偿失。

5    方案比较

经过上面的分析,想必对C#托管代码和C++本地代码以及C#通过P/Invoke方式调用C++本地代码的优劣性都有一定的了解了,本章将针对Mobile 2的具体需求以及系统瓶颈的分析,分类比较其优缺点。
Mobile运行于移动嵌入式平台上,硬件资源的非常有限,使得开发人员对资源合理分配与使用尤为重要,但对于一个设计生命周期相对较长的产品线来说,灵活的框架以及快速开发灵活部署的特性也非常重要,往往效率与灵活的框架是相冲突的,怎么样的权衡取舍,才能得到更加成熟的产品设计呢?首先针对Mobile进行瓶颈分析,确定合理的解决方案。

5.1    Mobile系统瓶颈分析

Mobile 1的项目已经实施完毕,对于嵌入式平台的开发积累下了丰富的经验,下面一组数据更加准确的说明的 Mobile 1性能的瓶颈分布,从而对改善Mobile的设计方案有着积极的影响。

  • 用户变更页面初始化过程耗时分布数据
步骤 耗时(ms)
初始化窗体 17
初始化 控件 32
初始化对象 9
方法调用与参数传 递 1
访问数据库 479
合计 538

 

  • 用户变更页面初始化过程耗时分布图示


由上面的图例及数据显示,Mobile 1中,主要的性能瓶颈在于DB的访问阶段,而Mobile 2的功能定义中,数据库的访问负荷并没有比Mobile 1中有所减少,所以从Mobile 1中的经验得知,Mobile 2的性能瓶颈主要还是集中在DB访问层面,先不讨论Windows Mobile 系统硬件资源优于Symbian,也不用考虑MS SQL Server CE的性能是否优于Oracle Lite,单纯从业务模型上分析,单个业务的相对耗时瓶颈还是在数据库访问上,因为Mobile 2中并不包含耗时算法或者复杂运算,所以如何改善DB性能决定了整个Mobile 2的整体性能,而作为程序设计语言来说,对系统整体性能的影响是相当微小的。

5.2    C#托管代码与C#调用C++本地代码的比较

下面针对两种模式进行针对性的对比,并进行感官评估打分,为Mobile 2的架构模型选择提供参考数据。

对比项目 C#托管代码 C#托管代码调用C++本地Dll
执行效率   3 5
可以执行    5 2
开发周期 5 3
代码可重用性 5 2
DB访问性能能 5 5
跨平台支持 5 3
MUI多语言支持 5 5
运行时多态性 5 2
界面的灵活性 5 3
合计 43 30

注:得分高代表该对比项目优秀,反之亦然

5.3    方案选择

由上面图表可知,C++本地代码的效率高于C#托管代码效率,但由于Mobile 2中整体系统的瓶颈并非在于可执行程序的算法上面,而是IO方面的性能损耗非常大,并且C#托管代码访问数据库与C++本地代码访问数据库的性能是相同的(使用的是同一套SQL Server CE的API),那么如下方法可以计算出两种方案的性能差距:
DB访问占整体耗时比例:479(DB访问耗时) / 538(完整业务耗时) = 89%,那么C#托管代码的效率与C#托管代码调用C++Dll的效率的区别仅仅在于另外的11%中,如上图中数据显示,C#调用C++Dll的方法仅能对系统整体性能中的11%提升40%左右,既然数据库的访问时间是固定的,那么C#托管代码调用C++本地代码的效率最高能够提升4.4%,这是一个微乎其微的数字,为了这4.4%而损失.Net Compact framework众多优良特性是非常不值得的。

综上所述,纯C#托管代码的的综合特性优于C#托管代码通过P/Invoke调用C++本地代码,

5.4    实施过程中的特殊情况

由于实施过程中,不可预知的特殊情况时有发生,为了满足不同的且特殊的需求,.Net托管代码通过P/Invoke方式调用C++编写的高效率本机代码仍然是一个不错的解决方案,由于P/Invoke属于.Net Compact framework 包含的特性,不需要另行的开发与部署即可使用该功能,所以,Mobile 2的开发过程中并不排除特殊情况使用该特性的可能。

6    总结

.Net 的优秀特性在于其丰富的运行时库支持,方便高效的开发模式,以及及时准确地垃圾收集机制,高效的即时编译特性能够有效地提升系统整体能能,跨平台支持,可以使程序集一次编译后跨平台部署,丰富的分辨率敏感自动停靠控件可以使开发人员不必维护屏幕分辨率不同给界面带来的影响等,这些优良特性使得.Net Compact framework托管代码的优势显而易见,微软的FAQ中也提到,企业级应用并不涉及复杂高负荷预算时,使用.NET Compact Framework开发即可满足性能需求,即便相较本地代码的执行效率会有所损失,但这样可以获得最好的灵活性和可移植性。

7    参考资料


• Microsoft .NET Compact Framework 开发常见问题解答
http://www.microsoft.com/china/msdn/library/NetFramework/netcompactframework/understandingnetcfFAQ.mspx

• 了解如何使用 .NET Compact Framework 的平台调用 (P/Invoke) 功能:
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfintrointerp.asp

• 了解如何使用 .NET Compact Framework 在托管和非托管代码之间封送数据。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfmarshallingtypes.asp
 
• 了解如何使用 dumpbin.exe 作为在基于 Microsoft .NET Compact Framework 的应用程序中声明 P/Invoke 的手段。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfdumpbinpinvoke.asp

  • 大小: 43.8 KB
分享到:
评论

相关推荐

    C#调用C++项目生成的dll文件

    接下来,是C#调用C++ DLL的关键步骤: 1. 引用DLL:在C#项目中,需要使用`using System.Runtime.InteropServices;`命名空间,这是.NET Framework提供的互操作性支持。然后,使用`[DllImport]`特性声明DLL,并指定...

    Vlc.DotNet-develop.zip

    P/Invoke允许.NET代码调用非托管代码,如C或C++库中的函数。 3. **事件驱动编程**:Vlc.DotNet可能使用事件驱动模型来处理播放、暂停、停止等操作。事件是.NET框架中的重要概念,允许组件之间通过触发事件进行通信...

    DotNet平台DLL动态加载示例

    这些方法适用于加载托管代码,而`DllImport`适用于加载非托管(如C++)代码。 - 如果DLL是.NET的,还可以通过反射加载类型和方法。 总结,DLL动态加载是.NET平台上的一个重要特性,它允许程序在运行时动态地添加...

    Pro VisualC++ CLI 2008 dotNet3.5 platform +源代码

    通过实际编码,读者可以了解如何使用C++/CLI创建.NET组件,如何调用.NET Framework的API,以及如何与其他.NET语言(如C#或VB.NET)进行互操作。这些示例涵盖了从简单的数据类型操作到复杂的设计模式应用,对于提升...

    c# 基于VLC播放器.zip

    集成VLC时,需要注意的是,由于VLC是用C++编写的,所以必须使用P/Invoke或托管C++来调用其API。`Vlc.DotNet`库是C#对VLC的封装,简化了这个过程,但仍然需要理解VLC的底层工作原理。 在调试和发布时,确保正确配置...

    doutnet源代码及系统架构资料

    例如,P/Invoke机制允许.NET代码调用本机代码,这对于与操作系统接口或使用C/C++编写的库时尤其重要。同样,interop服务让不同语言间的互操作成为可能,扩展了dotnet的适用范围。 源代码的学习还涉及到编译器和语言...

    C#编程基础

    2. **安全性**:通过类型安全系统和托管执行环境,C#能够避免许多常见的编程错误。 3. **简单易学**:对于熟悉其他C系列语言的开发者来说,C#的学习曲线较为平缓。 4. **高性能**:虽然是一种高级语言,但C#通过JIT...

    Dotnet Hacking & Detection --haya.pdf

    例如,使用execute-assembly工具和SharpWeb进行代码执行,就可以实现将可执行文件放在本地,并通过托管类语言抓取浏览器密码等操作。攻击者可能利用这些技术进行渗透测试或安全评估,而防守者则需了解这些攻击手段以...

    使用.NET Framework扩展MFC程序

    "Addison.Wesley.Extending.MFC.Applications.with.the.DotNET.Framework.chm"这本书很可能详细地介绍了这个过程,包括如何设置项目、编写C++/CLI代码、调用.NET组件以及解决潜在问题。通过阅读这本书,开发者可以...

    c# 入门学习掌握基本知识

    公共语言运行时(Common Language Runtime, CLR)是 .NET Framework 的核心组件之一,负责执行管理代码,并为托管代码提供内存管理、线程管理和异常处理等服务。公用语言规范(Common Language Specification, CLS)...

    C#语法入门 初学者适用

    - **现代化**:C#吸收了Java、C++等语言的优点,并在此基础上进行了创新,使得其更加简洁高效。 - **面向对象**:C#是一种完全支持面向对象编程的语言,提供了封装、继承、多态等关键特性。 - **安全性**:通过...

    播客.NET_dotnet影音娱乐网站.rar

    这些第三方库通常通过PInvoke(Platform Invoke)或.NET的托管包装技术,使得.NET应用可以调用原生C/C++库的功能。 此外,为了实现播客订阅和下载功能,该应用可能还利用了RSS(Really Simple Syndication)或Atom...

    ZLib dotNet Wrapper-开源

    3. **C++ 混合模式实现**:这个项目使用了 C++/CLI(Common Language Infrastructure),这是一种可以在 .NET 平台上运行的 C++ 语法变体,它能够与 .NET 元数据和托管代码交互。这种实现方式可以充分利用 C++ 的...

    Video-Files

    虽然FFmpeg主要是用C和C++编写的,但通过PInvoke(Platform Invoke)技术,C#开发者可以调用其动态链接库,实现视频的读取、写入、转码等功能。 3. **NAudio**: NAudio是C#的一个开源音频处理库,支持多种音频格式...

    .NET包装的Irrlicht引擎

    在这个案例中,C#包装器为Irrlicht引擎提供了一个接口,使得C#程序员可以利用.NET的语法和特性直接调用Irrlicht的功能,而无需直接处理底层的C++代码。这极大地简化了开发过程,提高了开发效率。 Irrlicht引擎本身...

Global site tag (gtag.js) - Google Analytics