微软专家:为什么VC++.net作的managed应用会对kernel32.dll有依赖?

horris 2002-07-01 01:12:53
我装了Visual Studio.net,用VC++.net,VB.net,C#分别编译了几个managed application(exe),我听说.net是一次编写,到处运行的,它的managed应用是编译成中间语言代码的,不是目标机器码。但是我用vc++.net作的C++ managed应用,用Depends查看却发现它对Kernel32.dll和mscoree.dll有直接依赖,而用C#作的只对mscoree.dll有依赖。后者好理解,mscoree.dll就是.net运行时的一部分吗,但是kernel32.dll是怎么回事,难道我期望Unix(假设已有了用于Unix的.net)上也有这个dll吗?是否VC++.net作的managed应用都是managed和unmanaged混合的代码,而不能作纯的managed应用?
...全文
202 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
horris 2003-05-11
  • 打赏
  • 举报
回复
即然要强行结贴,那就结吧
horris 2003-05-11
  • 打赏
  • 举报
回复
to ccBoy:你讲的所谓“C是二进制级跨平台”,实际上是源码级跨平台。Java实现了二进制级跨平台,就是编译以后的文件,拿到哪个OS都能用,当然那个OS要支持JVM。我要的就是这个,比如,我用.net编译后的东东,拿到Solaris直接就能用(假设将来某天Solaris也支持CLR了),而不是还要在Solaris上用源码重编译,要是还得重编译,我用.net干嘛?早就有源码级跨平台的方案嘛。
用C#和VB.net编译的程序,直接依赖没有kernel32,唯一的直接依赖是mscoree,当然mscoree间接依赖kernel32,不然它无法在Windows上运行。可以认为mscoree就是CLR。可为什么vc.net直接依赖就有kernel32呢?这就是说,C#作的.net和VC.net作的不一样,将来C#的跨平台(假设今后有一天实现了)没问题,而VC.net作的必定不行,因为它还依赖kernel32。
我的问题有这么多人回答,还没有一个让我满意的。
hihin 2003-05-09
  • 打赏
  • 举报
回复
楼主:
这里的确有很多人拿着三八大盖问怎么拉枪栓的问题。
作为一个论坛,总不能不让别人问吧?
高手很多,也很强,都是可遇不可求的。
小气的神,果然非常强啊
ccBoy 2003-05-07
  • 打赏
  • 举报
回复
to Fzgta
我非常同意"是不是托管代码,并不是强调/CLR的参数问题"的论断。

__gc不是C++的一部分,而是ms对c++的扩展一般我们会说这是MC++(managed extensions to C++),你可以试一下,只要你的代码中有了__gc (MC++另外定义了17个这样的关键字)编译参数就肯定要有/CLR 不然不会编译过去的(当然可能Cl.exe会自己加上,这个可以通过看PE来得出这个编译的二进制文件是托管的还是非托管的,用ildasm也可以),我想编译器是这样判断的,只要你的代码中有一个MC++的关键字,你整个的应用都是托管的了。之前我的描述有些简单,误倒了说只要加/CLR参数就会是托管的

MC中允许"Mixing Managed and Unmanaged Code",这时候是通过MC++的关键字#pragma unmanaged 和#pragma managed 来化分代码段,但无论怎样这个程序本身还是托管的,只不过是用这个语句告诉CLR不用管#pragma unmanaged注释段的资源和内存,这个对应C#中的unsafe关键字,VB.NET则没有这个功能.

to horris :

没有证据显示"C#和VB.NET作的程序就没有对kernel32的依赖"或是什么样的有依赖,什么样的没有,关键在于现在所有的托管代码最后都会即时编译成机器码运行在OS上,如果OS是Windows,那么它可能依赖kernel32,主要是OS.因为你不知到运行在W2K上的C#或VB.NET的应用是否还对user.exe或user32.dll有依赖:)
另外简单一点你用ildasm你可以查到你的EXE或DLL中有没有和kernel32有关系,但这并不意味着CLR不依赖啊.

目前二进制级的跨平台只有C,C++都不完全,Java是借助虚拟机,.NET借助的是IL+CLR。
.NET现在唯一的弱点就是所谓的跨平台,这是J2EE的梦想和卖点。至于Web Service不是.NET的卖点,对Web Services的完全支持、高生长率的开发是Microsoft的卖点,这是.NET对XML原生支持产生的一个可以看得见的优点,Soap Toolkit,ATL Server都是微软对开发WebServices的支持,另外是对已有COM或编程技术投资的保护,事实上这两个都在开发Web Services上都有缺点,相对来说C#,VB.NET是最经济和省时的选择。

对于JIT和GC性能的优劣,这个历史早有争议,我不想多说,但目前看来微软已经将这两个的技术做到了目前所有平台的极限(也就是最好的),.NET Framework1.1之后微软想的是借助Application Server 和OS再加强有关JIT和GC带来的负面影响,再提供高性能。这方面J2EE已经无能为力了,IBM和BEA都在自己的产品中使用其它技术加强了这两个因素的销抵。


小气的神
2003.05.06
ccBoy 2003-05-06
  • 打赏
  • 举报
回复
这很简单也是让人非常迷惑的问题,但如果你知道CLR和Java虚拟机的最大不同,你就能够明白这个问题。
一个Managed的.NET应用在被CLR装入后一般会先进行一系列的证据收集、版本检查、读取元数据等等和安全检查,只有都通过这些之后,最后一步才是用即时编译器编译成机器码,再之后就提交给操作系统,而Java的虚拟机没有这个机制,它运行在自己的虚拟机沙盒中。
所以.NET是和平台相关的,它的多平台取决于除Windows平台之外的平台是否实现了CLR和操作系统交互的部分,目前微软提交给ECMA的是C#和CLR最核心的一部分,这些标准中并没有明确定义CLR到OS的这一部分。如果是Unix那么它的CLR实现部分应该和Windows平台下的不同。"我听说.net是一次编写,到处运行的"这倒不假,但也许不同平台会需要一次重新编译(也许不需要),但你不用修改源码,主要是IL可能因为不同的平台而不同。

另外如果你使用VS.NET 那么默认情况下VS.NET 会加入对kernel32.dll的引用,另外还会加上user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib 等等但这些并不表示你的.NET应用就都和这些DLL有关。是否有关取决你应用程序是否调用了平台的函数和CLR。

之外我不赞同楼上的几位观点,无论MC++,VB.NET,C#还是J#它们都说Managed的,都是基于.NET Framework所以从代码到中间代码(IL)到最后提交给OS的过程不会有太大不同。你会发现在VC++中,如果不加/CLR参数你的C++应用和以前的C++应用没有什么不同,完全是机器码的,也就是非托管的。但加了/CLR之后它就成托管的了。还有一个观点就是CLR不是完完全全的.NET EXE,它是由托管代码和非托管代码组成的一个核心部件,但所有的应用必须是布尔的,要么是托管的,要么是非托管的。

小气的神
2003.05.06
horris 2003-05-06
  • 打赏
  • 举报
回复
为什么C#和VB.NET作的程序就没有对kernel32的依赖呢?
如果真如ccBoy所言,我对.net作应用的兴趣大减了,因为一,其不能保证二进制级的跨平台,何必还要用于.net?源代码级的跨平台难道C++就不行吗?二、.net的另一卖点,Web Service,现在已经有了for COM的Soap Toolkit以及编译成本机目标码的Web Service工具--ATL Server。何必还要忍受即时编译造成的性能损失呢?
蝈蝈太阳 2003-05-06
  • 打赏
  • 举报
回复
通意楼上的意见,但是,是不是托管代码,并不是强调/CLR的参数问题,
如果在你的代码中__gc定义了所有的代码,并且类型也全都是托管的,编译的代码自然是托管的。
当然/CLR强制编译成托管代码的,但是也不完全,根本还是取决你的代码。
如有,如有不同意见,可以继续讨论。
lolo68 2002-07-23
  • 打赏
  • 举报
回复
利用VC.net是存在本机代码(主要是启动部分,如果你清楚托管C++必须有非托管启动代码),如果使用C#这不会用这部分代码(不会直接依赖本机代码,而是依赖Pal层)。也就是说利用托管C++编写的代码目前不是完全可移植的,但利用C#编译的代码是可移植的。提供托管C++更多的目的是顺利移植已有C++代码到.net平台,而不是产生完全的不含本机代码的程序。所以,如果你尝试过sscli的话,你会发现不可以与托管C++混合的。
如果对clr的内部感兴趣,或者对于C#编译器感兴趣,建议阅读sscli部分代码(www.microsoft.com/net)。目前可以支持Windows及FreeBSD. 看一下Pal目录你就会明白很多,另外也有一个关于Pal的移植文本,可以认为Pal实现了一个微型Windows API,当然Win32平台很简单,但如果移植这应该实现这些API,你可以看看FreeBSD的例子,当然如果彻底移植还要考虑jit的移植。
jackalwisdom 2002-07-21
  • 打赏
  • 举报
回复
ms的.net vc++.net中文版何时出,它可能会有这方面的解释,现在市场上关于.net的书太烂了
jackalwisdom 2002-07-21
  • 打赏
  • 举报
回复
还有就是ms在c++保留非托管代码是出于性能的考虑,这就要和native有关
jackalwisdom 2002-07-21
  • 打赏
  • 举报
回复
我想关键是在c++中main()入口不是包装在类中的可能还要和native有关,
另外.net毕竟是c#是主语言
daehappy 2002-07-21
  • 打赏
  • 举报
回复
up!gz!
horris 2002-07-21
  • 打赏
  • 举报
回复
我这有VS.net,声称是中文正式版,2002.3.22出的,不知是不是真正的正式版?.net SDK中好些名字空间的组织与测试版不一样了.我还没有在MSDN文档中找到这方面的说明.
horris 2002-07-08
  • 打赏
  • 举报
回复
谢谢Muf,你使我知道从哪下手了
horris 2002-07-08
  • 打赏
  • 举报
回复
那么怎么样才能使C++.net应用不混合native代码呢?在哪里可以设置?
C++.net managed dll也是有kernel32.dll依赖的。
horris 2002-07-06
  • 打赏
  • 举报
回复
拜托不要跑题,我知道所有的Windows应用对kernel32.dll有依赖,确切地说应该叫Native应用,但是managed应用不是Native应用。
这个贴子都放这快一周了,没有人提供一点有价值的回答,倒是有人答非所问。看看这个坛子,都是些爱上层楼的极菜鸟问题,干脆关了算了,别再误人子弟,继VC菜鸟,又培养出一批.net菜鸟来!
Muf 2002-07-06
  • 打赏
  • 举报
回复
c++.net managed 的dll文件是不是就不清楚了,我没用过,最好还是自已摸摸吧。摸清了给我们讲讲,也让我们菜鸟进步进步。
Muf 2002-07-06
  • 打赏
  • 举报
回复
你知道managed应用是如何被装载的吗?
c++和vb.net及c#是不同的。
c++.net产生的managed应用通常(但并不都是)混合了native和managed的代码;它产生装载managed运行环境,建立.net domain,然后将managed代码启动。
而vb.net和c#不一样,它只是产生managed代码,由操作系统预定义的程序(由.net安装程序设置)装载运行环境,并建立.net domain,然后才把managed代码在其中启动。

也许你会在debug时,由ide环境产生的装载信息体会到它们的不同之处。
==============================
参考:
1. SDK文档:FrameworkSDK\Tool Developers Guide\docs\*.doc
2. MSDN:Application Domain 应用程序域 (.net)
louisexiuxiu 2002-07-05
  • 打赏
  • 举报
回复
我乡
Muf 2002-07-05
  • 打赏
  • 举报
回复
所有的Widnows应用程序对kernel32.dll都有直接依赖。
加载更多回复(3)

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧