在 VC++(本机)中可以完成哪些 VC# 无法完成的事情?

Posted

技术标签:

【中文标题】在 VC++(本机)中可以完成哪些 VC# 无法完成的事情?【英文标题】:What can be done in VC++ (native) that can't be done with VC#? 【发布时间】:2009-04-16 16:39:10 【问题描述】:

据我所知,唯一值得使用 VC++ native 的事情是当您需要自己管理内存而不是 CLR 垃圾收集器时,我也没有看到这样做的目的(但那是另一个问题后来问)。

【问题讨论】:

【参考方案1】:

跨平台开发。是的 Mono 存在,并且 Java 的 有点 更可预测,使其在更多平台上的功能完全相同,您可以找到适用于几乎任何平台的 C/C++ 编译器,而 C# 则无法使用.

还链接到第 3 方库,虽然我确信有一种方法可以在 C# 中利用它们,但您将能够利用它们而无需在 C++ 中进行互操作(编组等)。

编辑:最后一件事:可靠的内存管理。是的,您可以使用dispose()try-finally,但没有什么比知道内存从堆栈中弹出时消失了。通过 RAII 等技术,当您使用构造良好的类时,您将知道您的类何时释放资源,而不是等待 GC 发生。

【讨论】:

没有问“在 Java 中可以完成哪些 VC# 无法完成的事情?”。 当然不是,但如果我不提,cmets中的某人会跟我说推荐Java进行跨平台开发。 您的最新评论应该说,可靠的资源管理。尝试/最后不要剪得太容易出错,'with' 非常适合本地管理资源,但对于共享资源,没有什么能像 RAII 那样剪裁。【参考方案2】:

使用 P/Invoke 在 .NET 中不可能几乎没有(最明显的是设备驱动程序)。

还有一些建议是不要使用 .NET(例如,shell 扩展,它会被加载到任何打开文件对话框的进程中1)。

最后,如果可能的话,在 .NET 中有些事情会更加困难(例如,创建一个聚合 FTM 的 COM 组件)。

1 如果该进程已经在使用不同版本的 .NET,这可能会产生问题。随着 .NET 4 能够支持运行时的并行实例,这种情况应该会在未来得到缓解。

【讨论】:

【参考方案3】:

我不确定您说的是语言功能还是应用程序。我的回答是针对应用程序/组件。

确实,只有 2 件事在 C# 中无法做到,而在 C++ 中却可以做到。

您不能使用 C# 或任何其他 .Net 语言为仅接受本机组件的系统编写组件 您不能使用 C# 或任何其他 .Net 语言来更改 CLR 不允许自定义的 CCW 的某些属性

这里最值得注意的项目是设备驱动程序。这是一个只接受原生组件的框架,无法插入托管组件。

对于其他任何事情,在 C# 中都可以像在 C++ 中那样做同样的事情。在很多情况下,您根本不想这样做,而本机解决方案更好。例如,可以通过不安全代码或 IntPtr 在 C# 中管理和操作内存。这几乎没有那么容易,而且通常没有理由。

【讨论】:

你对我的问题的意图是正确的。它与应用程序相关。谢谢! “真的,只有两件事你不能在 C# 中做而你不能在 C++ 中做。” 什么? =S @John 我试图在帖子的第一段中澄清这一点。此声明与您在构建应用程序/组件方面可以做什么有关。不是语言功能 @JaredPar 我认为他的意思是你说不能两次 @Caspin,哈哈!完全错过了(固定)。至少我对这样的错误有点幽默。【参考方案4】:

你不能为一个人编写设备驱动程序。

【讨论】:

【参考方案5】:

我认为有几点很重要:

你可以用 C#/C++/Java/Python/Lisp 或几乎任何其他语言做任何事情,最后它们都图灵完备;)...问题是它适合你的需要吗?

    C# 有一个 且极其重要的限制...它只能运行 一个 单平台 Windows...(Mono 仍然不是 mature enough)。 在许多应用程序中,GC 只是浪费资源,在下一个 gc 周期之前无法占用 1/2 内存的应用程序:游戏、数据库、视频音频处理和许多其他关键任务应用程序。 实时应用程序(同样是游戏、视频处理等)。非确定性 GC 让他们的生活变得更加艰难。

事实上,大多数桌面应用程序:Web 浏览器、文字处理器、桌面环境本身(如 Windows 资源管理器、KDE ​​或 Gnome)都是用编译语言编写的,并仔细考虑了资源……否则,它们只会变得臃肿不堪应用程序。

【讨论】:

【参考方案6】:

虽然在 C# 中可以在 Windows XP 中编写 shell 扩展,但在 Vista 和 Windows 7 中编写 shell 扩展几乎是不可能的。Shell 扩展和命名空间扩展(以及使用新属性系统的任何其他内容)(kindof)必须是在 C++ 中完成,除非您遇到痛苦

【讨论】:

【参考方案7】:

有两个明显的答案:

VC# 不能在没有 .NET 的情况下运行 框架。本机 C++ 可以。那可能 在某些领域是必要的(其他 提到了设备驱动程序,但是 更常见的例子可能只是 .NET 框架所在的客户端 未安装。也许你是 分发应用程序和您 知道并非所有客户都是 愿意安装 .NET,所以你的 如果你制作了一个应用程序,销售额会上升 没有 对 .NET 的依赖。或许你是 在某些移动设备上工作 占用的几兆字节 .NET CF 是不合理的。或者使用 .NET 的 shell 扩展可能会给用户带来麻烦。 而且VC#永远不能用C++语言 特征。本机 C++ 可以。 (管理 当然,C++ 也可以,但那是 不同的问题)。信不信由你,在 C++ 中可以更方便或更优雅地完成一些事情。只有在使用 C++ 编程时才能访问它们。

不过,系统调用没有问题。 p/invoke 让您可以使用 C# 执行这些操作,几乎与使用 C++ 一样容易。

【讨论】:

您只需要一个编译器 + 一个特殊的链接器即可将应用程序的 IL 代码和使用的库转换为本机代码。 第二部是开玩笑的吧? 顺便说一句:某些系统调用可能是个问题,因为并非所有 c 函数都可以通过 P/Invoke 调用(例如,需要回调的函数) 我认为理智的人不会期望能够在另一种语言中使用一种语言的语言特性。 “你只需要一个编译器+特殊链接器”,是的,没有类似的东西,所以你的评论有点滑稽。 Mono 有一个,但没有 .NET。您能否将 MS 的 .NET 框架(以及所有依赖项在没有源代码的情况下链接在一起?)【参考方案8】: 内联汇编器 您不能将 C++ 库与类一起使用(P/Invoke 只能用于函数 AFAIK) 您不能在 P/Invoke 中使用回调。

【讨论】:

【参考方案9】:

特别是 C# 和 .NET 一般是自编译吗(这不是巨魔,我真的不知道)?如果没有,您可以使用 VC++ 编写 C# 和 .NET,但不能使用 C# 完成相同的工作。

【讨论】:

C#是否是图灵完备的,你的问题真的有效吗? 不,Neil 询问编译器和运行时是否是自托管的。我不知道(因为我不在 Microsoft 工作),但基于 Rotor(他们发布的“共享源”东西)我强烈怀疑它们不是自托管。甚至在 Mono 是自托管的意义上也没有。 不 - 这显然是图灵完备的,但 QBasic 也是如此!仅仅因为一种语言是 TC 并不意味着您可以使用它来直接实现其他系统。您显然可以间接地做到这一点 - 例如用QBasic写一个汇编器,用汇编器来.... 在一些 MSDN 博客,或者(可能)第 9 频道视频中:本机编译器的工作是(1)更易于维护,(2)用于语法检查/智能感知/.. . 在 VS 中(并给出与编译完全相同的结果)。但这是,IIRC,目标超出 .NET 4。【参考方案10】:

这是在开玩笑,但它也是对您的问题的回答……在 VC++ 中,您可以比在 VC# 中更严重地搞砸事情。并不是说你不能在 VC# 中把事情搞砸,但总的来说,你可以在 VC++ 中更轻松、更彻底地搞砸。

再一次,有点开玩笑,但也是对您问题的回答。也许不是您所希望的,但是... :-)

【讨论】:

我一次又一次地听到这种观点,但在 MFC 和 .NET 项目中都工作过,我的经验告诉我完全相反。我认为它主要基于理论而不是实践。 鉴于 File.Delete 和 RegistryKey.DeleteSubKey 在 .NET 中,很容易搞砸。那是在接触 ACL 或 P/Invoke 之前。把事情搞砸并不需要太多。 您可以在 C++ 中完成所有这些操作,而且在 C# .oO(bad pointers) 中无法搞砸的更多内容 我认为 C# 中最大的“搞砸”可能是内存管理 - 查看 .Net 中不希望的对象保留的问题。最大的原因是每个人都被告知这不可能发生,所以他们甚至没有考虑内存泄漏。 第二个可能是性能问题——可能是因为他们认为语言/编译器/框架会为他们处理好一切。【参考方案11】:

还有硬实时应用程序。不能使用任何带有 GC 的语言,以防它决定在代码的时间受限部分进行收集。 Java 因甚至不允许您尝试而臭名昭著(因此 EULA 关于不将其用于“旨在用于任何核设施的设计、建造、运营或维护”的软件

(是的,我知道他们已经为实时系统制作了 Java 的修改版本)。

【讨论】:

【参考方案12】:

例如,如果翻译现有库的头文件比放弃现有托管库更难,那么使用 C++ 是有意义的。

【讨论】:

【参考方案13】:

主要区别在于:

C++ 是一种核心语言,您可以使用它构建独立程序。这些程序直接与操作系统通信,而不是其他任何东西。 C++ 编译器几乎适用于所有平台(操作系统)。

C# 是一种符合 CLS 的语言。如果没有 CLI 引擎(.NET Framework、Mono 等),用 C# 编写的程序就无法启动。用 C# 编写的程序与 .NET 框架和操作系统进行通信。你中间有个男人。像所有服务人员一样,这个人可以提供帮助,但会造成额外的麻烦。如果你想移植,中间有一个不同的人等等。并非所有平台都存在 CLI 实现。

在我看来,每一个额外的框架都是额外的问题来源。

【讨论】:

使用该逻辑,操作系统是问题的根源。您应该避免所有问题并在 Bios 级别编写应用程序。 您可能有不同的观点,但根据我对大型长期项目的经验,我清楚地看到,如果您不依赖比大麦更多的 3d 派对材料,它会更强大,而且确实更便宜。 【参考方案14】:

使用 SSE 指令似乎是其中一种情况。一些 .NET 运行时将使用一些 SSE 指令,具体取决于您的代码。但在 VC++ 中,您可以直接使用 SSE 内在函数。因此,如果您正在编写多媒体代码,您可能需要 C++。 (大概 C++/CLI 也可以工作)

【讨论】:

以上是关于在 VC++(本机)中可以完成哪些 VC# 无法完成的事情?的主要内容,如果未能解决你的问题,请参考以下文章

开发驱动程序 主要会用到VC++的哪些内容?

VC++中通过CreateThread创建的线程,当线程入口函数执行完后,线程自己会关闭吗?

win10无法运行vc6.0怎么办

vc获取本机外网IP,怎么获取,求源码。

VC修改本机IP地址

vc++6.0一打开就出现应用程序错误,无法正常启动0xc0000142