【问题标题】:Options for refactoring bits of code away from native C++?从原生 C++ 重构代码位的选项?
【发布时间】:2008-09-29 03:11:00
【问题描述】:

因此,在谈论性能时,一个常见的评论是,您使用任何可以最快完成工作的语言编写代码。如果特定领域的性能有问题,那么用 C/C++ 重写那些位。

但是,如果您从本机 C++ 应用程序开始呢?如果你想用 Python、Ruby、C# 或其他语言编写简单的部分或重构旧的部分,你有什么选择?请记住,在本地和其他端之间传输数据是必须的。能够简单地调用用“更简单”的语言编写的函数,同时将 C++ 类作为数据传递,这将是非常美妙的。

我们有一个硬核的 Win32 应用程序,如果我们可以用 C# 或其他方式编写新代码或重构旧代码,它将会受益匪浅。其中很少需要 C++ 的复杂性,处理这些小细节会拖累编程过程。

【问题讨论】:

    标签: c++ performance refactoring native


    【解决方案1】:

    正如Aaron Fischer 建议的那样,尝试在打开 /clr 选项的情况下重新编译您的 C++ 应用程序,然后开始利用 .Net 平台。

    如果您已经了解 C# 和 C++,那么 CLI/C++ 非常容易上手,它提供了 .Net 世界和原生 C++ 之间的桥梁。

    如果您当前的 C++ 代码无法在打开 /clr 的情况下干净地编译,那么我建议您尝试将您的应用程序构建为静态库(未启用 /clr),然后让您的 main() 位于 CLI/调用旧应用程序入口点的 C++ 项目。这样,您至少可以开始利用 .Net 开发新功能。

    有关已“移植”到 .Net CLI/C++ 的“旧版”C/C++ 应用示例,请查看 Quake 2Quake 3: Arena 的 .Net 端口。

    【讨论】:

      【解决方案2】:

      嗯,这真的取决于语言。例如,Python 接口最容易使用 Boost Python 完成,许多其他语言将要求您像使用 C 一样使用它们的 C 库并声明您的回调是 extern "C"(不幸的是,您可以' t 通常使用其他语言中的 C++ 类定义)。

      但我也想问你打算用它来做什么,因为 C++ 是一门复杂的语言,但是一旦你熟悉了它,它就非常强大,并且与其他语言相比并不难编码。我能想到的唯一真正好的例外是,如果您打算使用仅以一种语言存在并且没有像样的 C++ 替代品的强大库(图形库可能是最好的例子,因为您必须非常熟悉与他们一起有效地使用它们)。

      还值得指出的是,如果您将 C++ 代码与另一种语言接口,您将失去该语言授予的跨平台兼容性。

      【讨论】:

        【解决方案3】:

        如果您想在 C++ 和 Python 之间工作,那么Boost Python 就是您要找的。您可以为 Cython 手动编写 C Python 绑定,但这在许多方面限制了您编写代码的方式。这是最简单的方法,从this tutorial 的一些 sn-ps 中可以看出:

        一个执行 hello world 的简单函数:

        char const* greet()
        {
           return "hello, world";
        }
        

        将其暴露给 python 所需的 Boost python 代码:

        #include <boost/python.hpp>
        
        BOOST_PYTHON_MODULE(hello_ext)
        {
            using namespace boost::python;
            def("greet", greet);
        }
        

        如何在 python 中使用这段代码:

        >>> import hello_ext
        >>> print hello.greet()
        hello, world
        

        朝相反的方向前进会有点困难,因为 python 不会编译为本机代码。您必须将 python 解释器嵌入到您的 C++ 应用程序中,但这样做所需的工作记录在 here 中。这是一个调用python解释器并提取结果的例子(python解释器定义了在C++中使用的对象类):

        object result = eval("5 ** 2");
        int five_squared = extract<int>(result);
        

        【讨论】:

          【解决方案4】:

          您可以将 c++ 项目中的公共语言运行时支持更改为 /clr。从这一点开始,您可以在您的 c++ 代码中使用任何 .net 功能。这也包括在您的项目中创建 winforms。您还可以添加处理 ui 和其他功能的 c# 库。

          【讨论】:

            【解决方案5】:

            在 .NET 世界中,您始终可以选择为 C#/VB.NET 程序集创建 COM/ActiveX 互操作层。

            然后,您可以使用 C++ 应用程序中的普通 COM API 创建此 COM 服务器的实例,该实例实际上包装了您的 .NET 程序集。

            这样做的好处是简单的参数,如 int、bool、string、float 等,都被映射到它们的 COM 等效项。但是据我所知,不可能轻松传递完整的 .NET 对象(您创建的类的实例)。

            还要注意 COM 互操作调用相对较慢。您不应该在紧密循环中不断地从 C++ 代码调用 COM 互操作方法。

            COM/ActiveX 传统上依赖于 Windows 注册表,这并不理想,因为它是一个很大的依赖项。不过也可以使用Registration-Free COM 互操作来避免这种依赖关系。

            This article 涵盖了为 COM 互操作注册 .NET 程序集所需的步骤。

            【讨论】:

              猜你喜欢
              • 2017-01-27
              • 1970-01-01
              • 2021-09-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-10-11
              相关资源
              最近更新 更多