Варианты рефакторинга фрагментов кода с использованием собственного C++?
-
02-07-2019 - |
Вопрос
Итак, когда речь идет о производительности, часто можно услышать комментарий: вы пишете свой код на том языке, на котором работа выполняется быстрее всего.Если производительность в определенных областях является проблемой, перепишите эти биты на C/C++.
Но что, если вы начинаете с собственного приложения C++?Какие варианты у вас есть, если вы хотите написать простые фрагменты или провести рефакторинг старых на таком языке, как Python, Ruby, C# или каком-то другом?Имейте в виду, что передача данных между нативной и другими сторонами обязательна.Было бы прекрасно иметь возможность просто вызывать функцию, написанную на «более простом» языке, передавая классы C++ в качестве данных.
У нас есть неплохое Win32-приложение, которое было бы очень полезно, если бы мы могли написать новый код или провести рефакторинг старого кода на C# или чем-то еще.Очень немногие из них требуют сложности C++, а обработка мелких деталей затягивает процесс программирования.
Решение
Как Аарон Фишер предлагает попробовать перекомпилировать приложение C++ с включенной опцией /clr, а затем начать использовать платформу .Net.
CLI/C++ довольно легко освоить, если вы уже знаете C# и C++, и он обеспечивает мост между миром .Net и собственным C++.
Если ваш текущий код C++ не может полностью скомпилироваться с включенным /clr, я бы предложил попытаться создать ваше приложение как статическую библиотеку (без включения /clr), а затем разместить свой main() в проекте CLI/C++, который вызывает точку входа вашего устаревшего приложения.Таким образом, вы сможете, по крайней мере, начать использовать .Net для получения новых функций.
Примеры «устаревших» приложений C/C++, которые были «портированы» в .Net CLI/C++, см. в портах .Net Квейк 2 и Квейк 3:Арена.
Другие советы
Ну, это действительно зависит от языка.Например, интерфейс Python легче всего реализовать с помощью Boost Python, а многие другие языки потребуют от вас взаимодействовать с ними так же, как с C, используя их библиотеку C и объявляя ваши обратные вызовы extern «C» (к сожалению, вы можете это сделать). Обычно я не использую определения классов C++ на других языках).
Но я бы также спросил, для чего вы собираетесь его использовать, поскольку C++ — сложный язык, но как только вы с ним познакомитесь, он станет очень мощным, и его не намного сложнее кодировать, чем другие языки.Единственное действительно хорошее исключение, о котором я мог подумать, это если вы планируете использовать мощную библиотеку, которая существует только на одном языке и нет достойной альтернативы C++ (графические библиотеки, вероятно, лучший пример этого, потому что вы должны быть очень хорошо знакомы с с ними, чтобы использовать их эффективно).
Также стоит отметить, что если вы связываете код C++ с другим языком, вы теряете межплатформенную совместимость, обеспечиваемую этим языком.
Если вы хотите работать между C++ и Python, то Ускорить Python это то, что вы ищете.Вы можете написать привязки C Python для Cython вручную, но это во многом ограничивает то, как вы собираетесь писать свой код.Это самый простой способ, как видно из некоторых фрагментов из этот урок:
Простая функция, выполняющая 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++, но необходимая для этого работа документирована. здесь.Это пример вызова интерпретатора Python и извлечения результата (интерпретатор Python определяет класс объекта для использования в C++):
object result = eval("5 ** 2");
int five_squared = extract<int>(result);
Вы можете изменить поддержку общего языка во время выполнения в проекте C++ на /clr.С этого момента вы можете использовать любую функциональность .net прямо в своем коде на C++.Это также включает в себя создание winforms в вашем проекте.Вы также можете добавить библиотеку C#, которая обрабатывает пользовательский интерфейс и другие функции.
В мире .NET у вас всегда есть возможность создать уровень взаимодействия COM/ActiveX для вашей сборки C#/VB.NET.
Затем вы можете использовать обычный COM API из вашего приложения C++, чтобы создать экземпляр этого COM-сервера, который фактически обертывает вашу сборку .NET.
Хорошо, что простые параметры, такие как int, bool, string, float и т. д., сопоставляются для вас с их COM-эквивалентом.Однако, насколько мне известно, невозможно легко передать полные объекты .NET (экземпляры созданных вами классов).
Также имейте в виду, что вызовы COM-взаимодействия выполняются относительно медленно.Не следует постоянно вызывать метод взаимодействия COM из кода C++ в тесном цикле.
COM/ActiveX традиционно полагались на реестр Windows, что не идеально, поскольку это большая зависимость.Однако также возможно использовать Регистрация без регистрации COM-взаимодействие, чтобы избежать этой зависимости.
Эта статья описывает шаги, необходимые для регистрации сборки .NET для COM-взаимодействия.