Integración de C# con otros lenguajes: desde P/Invoke hasta Python y JavaScript

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Por qué C# no vive en el vacío, y cómo funciona

\n\n

Cuando empecé a trabajar con C# hace unos diez años, me parecía que .NET era un universo autosuficiente. Bibliotecas, frameworks, bases de datos: todo al alcance de la mano. Pero luego llegó una tarea: necesitaba usar una biblioteca antigua de C++ para procesamiento de señales. Y entonces entendí: la integración de C# con otros lenguajes no es un lujo, sino una necesidad para cualquier proyecto serio.

\n\n

Hoy en día, C# es un lenguaje multiplataforma con un ecosistema rico, pero no puede hacerlo todo. A veces es necesario ejecutar un script de Python para machine learning, a veces invocar una función nativa de Rust para máximo rendimiento, y a veces incrustar un motor de JavaScript para la generación dinámica de UI. La buena noticia: C# sabe cómo llevarse bien con casi todos.

\n\n

En este artículo, mostraré escenarios reales de interacción de C# con otros lenguajes con código funcional, benchmarks y trampas. ¡Allá vamos!

\n\n

P/Invoke: el clásico del género para C y C++

\n\n

Platform Invocation Services (P/Invoke) es el mecanismo integrado de .NET para llamar funciones desde DLL nativas. Apareció en la primera versión de .NET y sigue siendo la forma más rápida de integrarse con código C/C++.

\n\n

Ejemplo básico: llamar a una función desde C

\n\n

Supongamos que tenemos una biblioteca nativa math_helper.dll con la función:

\n\n
// math_helper.h\nextern "C" __declspec(dllexport) double calculate_power(double base, int exp);
\n\n

En C# la conectamos así:

\n\n
using System.Runtime.InteropServices;\n\npublic class NativeMath\n{\n    [DllImport("math_helper.dll", CallingConvention = CallingConvention.Cdecl)]\n    public static extern double calculate_power(double base, int exp);\n}\n\n// Uso\ndouble result = NativeMath.calculate_power(2.0, 10);\nConsole.WriteLine($"2^10 = {result}"); // 1024
\n\n

Puntos importantes al hacer P/Invoke C#:

\n
    \n
  • Siempre especifique CallingConvention — normalmente Cdecl o StdCall.
  • \n
  • Para cadenas, use MarshalAs(UnmanagedType.LPStr) o LPWStr.
  • \n
  • Pase estructuras por referencia usando ref o out.
  • \n
\n\n

P/Invoke tiene una sobrecarga mínima: literalmente unos pocos nanosegundos por llamada. Si necesita integrar C# con C++ para cálculos de alto rendimiento, esta es su opción.

\n\n

C++/CLI: el puente entre mundos

\n\n

C++/CLI es una extensión de Visual C++ que permite escribir código que funciona tanto en entornos administrados (.NET) como no administrados. No es un lenguaje separado, sino un híbrido que se usa a menudo para crear envoltorios sobre bibliotecas de C++.

\n\n

Ejemplo de envoltorio para OpenCV

\n\n

Supongamos que tenemos una función en C++ que procesa una imagen:

\n\n
// NativeImageProcessor.h\n#pragma once\npublic ref class ImageProcessor\n{\npublic:\n    static System::Drawing::Bitmap^ ApplyFilter(System::Drawing::Bitmap^ bmp);\n};
\n\n

Internamente, llamamos a OpenCV nativo, y hacia afuera devolvemos un Bitmap administrado. Desde C# lo usamos como una biblioteca .NET normal:

\n\n
using ImageProcessorLib;\n\nvar img = new Bitmap("photo.jpg");\nvar processed = ImageProcessor.ApplyFilter(img);\nprocessed.Save("filtered.jpg");
\n\n

La integración con C++/CLI da control total sobre la memoria y evita el marshaling. La desventaja: el código se vuelve dependiente de la plataforma y más difícil de depurar.

\n\n

Python.NET: llamar a Python desde C#

\n\n

Python es el rey de la ciencia de datos y el machine learning. Y si su proyecto en C# requiere, por ejemplo, ejecutar una red neuronal en PyTorch o procesar texto con spaCy, llamar a Python desde C# a través de Python.NET es lo que necesita.

\n\n

Instalación y primer ejemplo

\n\n

Instalamos el paquete:

\n\n
dotnet add package Python.Runtime.NETStandard

Blogs

Book Recommendations