Saltar al contenido

¿Cuál es la diferencia entre pInvoke y COM Interop?

Hola usuario de nuestro sitio web, descubrimos la respuesta a tu interrogante, continúa leyendo y la encontrarás aquí.

Solución:

P / Invoke se utiliza para llamar a las API de C simple (como la mayoría de las API de Win32). La interoperabilidad COM se utiliza para llamar a objetos COM.

Puede crear un contenedor COM C ++ alrededor de una API C y luego usar la interoperabilidad COM para llamar a su contenedor si el número de llamadas API es relativamente alto (y puede usar el contenedor COM para encapsularlas en solo una o dos llamadas). Esto se debe a que la interoperabilidad nativa administrada puede ser relativamente costosa y es bueno minimizar el número de transiciones. Aunque en realidad diría que usar C ++ / CLI para crear el contenedor probablemente sería un poco más amigable para el lado C # (mirando SlimDX, por ejemplo, que es un contenedor C ++ / CLI alrededor de una API COM (DirectX)).

Habiendo dicho eso, a menos que tenga un problema de rendimiento específico, simplemente usaría el método que sea más natural para la API que está tratando de llamar: si es una API C (como la API de Win32), entonces use P / Invoke. Si está basado en COM, utilice la interoperabilidad COM.

La interoperabilidad le permite preservar y aprovechar las inversiones existentes en código no administrado. El código que se ejecuta bajo el control de Common Language Runtime (CLR) se denomina código administrado y el código que se ejecuta fuera de CLR se denomina código no administrado. COM, COM +, componentes C ++, componentes ActiveX y Microsoft Win32 API son ejemplos de código no administrado.

.NET Framework permite la interoperabilidad con código no administrado a través de los servicios de invocación de plataforma (P / Invoke), el espacio de nombres System.Runtime.InteropServices, la interoperabilidad C ++ y la interoperabilidad COM (interoperabilidad COM).

PInvoke utiliza el mecanismo de enlace dinámico para incorporar código externo al proceso de ejecución. Las bibliotecas de vinculación dinámica (DLL) deben tener la misma arquitectura de destino que la aplicación de llamada, por lo que no es posible realizar llamadas cruzadas de 64 bits a 32 bits o viceversa. En su lugar, la DLL se asigna al espacio de direcciones de la persona que llama y se ejecuta en proceso.

COM, DCOM, COM + y ActiveX se basan en bibliotecas de comunicaciones entre procesos, pero a veces se convierten en una simple carga de DLL. Los objetos vinculados a COM están relacionados, pero no son idénticos a los objetos CORBA, pero aunque CORBA desarrolló su propio localizador de objetos, la implementación COM todavía se basa libremente en las bibliotecas RPC y XDR de Sun Microsystems con extensiones para las características orientadas a objetos de COM. Los objetos COM no son referenciados por DLL, sino por un GUID que se usa para buscar la clase de objeto y consultar sus interfaces. El código objeto generalmente se ejecuta en un proceso separado o puede estar en un servidor separado.

Para lenguajes .NET, como Visual Basic y C #, el método prescrito para interoperar con componentes nativos es P / Invoke. Debido a que P / Invoke es compatible con .NET Framework, Visual C ++ también lo admite, pero Visual C ++ también proporciona su propio soporte de interoperabilidad, que se conoce como C ++ Interop. Se prefiere la interoperabilidad de C ++ sobre P / Invoke porque P / Invoke no es seguro para los tipos. Como resultado, los errores se informan principalmente en tiempo de ejecución, pero C ++ Interop también tiene ventajas de rendimiento sobre P / Invoke.

La clasificación de datos realizada por C ++ Interop es la forma más simple posible: los parámetros simplemente se copian a través del límite administrado / no administrado de forma bit a bit; no se realiza ninguna transformación. Para P / Invoke, esto es solo true si todos los parámetros son de tipo simple, blittable. De lo contrario, P / Invoke realiza pasos muy sólidos para convertir cada parámetro administrado en un tipo nativo apropiado y viceversa si los argumentos están marcados como “out” o “in, out”.

En otras palabras, C ++ Interop usa el método más rápido posible de ordenamiento de datos, mientras que P / Invoke usa el método más robusto. Esto significa que C ++ Interop (en una forma típica de C ++) proporciona un rendimiento óptimo de forma predeterminada, y el programador es responsable de abordar los casos en los que este comportamiento no es seguro o apropiado.

Por lo tanto, C ++ Interop requiere que la clasificación de datos se proporcione explícitamente, pero la ventaja es que el programador es libre de decidir qué es apropiado, dada la naturaleza de los datos, y cómo se utilizarán. Además, aunque el comportamiento del cálculo de referencias de datos P / Invoke se puede modificar hasta cierto punto, C ++ Interop permite personalizar la clasificación de datos llamada por llamada. Esto no es posible con P / Invoke.

P / Ejemplo de invocación a continuación:

using System;
using System.Runtime.InteropServices;

public class Win32 
     [DllImport("user32.dll", CharSet=CharSet.Auto)]
     public static extern IntPtr MessageBox(int hWnd, String text, 
                     String caption, uint type);


public class HelloWorld 
    public static void Main() 
       Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);
    

Ejemplo de interoperabilidad com (en C ++ que consume código c #)

// ConLoan.cpp : Defines the entry point for the console application.  
#include "stdafx.h"  
#import "..LoanLibLoanLib.tlb" raw_interfaces_only  
using namespace LoanLib;  

int main(int argc, char* argv[])  
  
    HRESULT hr = CoInitialize(NULL);  

    ILoanPtr pILoan(__uuidof(Loan));  

    if (argc < 5)   
      
        printf("Usage: ConLoan Balance Rate Term Paymentn");  
        printf("    Either Balance, Rate, Term, or Payment must be 0n");  
        return -1;  
      

    double openingBalance = atof(argv[1]);  
    double rate = atof(argv[2])/100.0;  
    short  term = atoi(argv[3]);  
    double payment = atof(argv[4]);  

    pILoan->put_OpeningBalance(openingBalance);  
    pILoan->put_Rate(rate);  
    pILoan->put_Term(term);  
    pILoan->put_Payment(payment);  

    if (openingBalance == 0.00)   
         pILoan->ComputeOpeningBalance(&openingBalance);  
    if (rate == 0.00) pILoan->ComputeRate(&rate);  
    if (term == 0) pILoan->ComputeTerm(&term);  
    if (payment == 0.00) pILoan->ComputePayment(&payment);  

    printf("Balance = %.2fn", openingBalance);  
    printf("Rate    = %.1f%%n", rate*100);  
    printf("Term    = %.2in", term);  
    printf("Payment = %.2fn", payment);  

    VARIANT_BOOL MorePmts;  
    double Balance = 0.0;  
    double Principal = 0.0;  
    double Interest = 0.0;  

    printf("%4s%10s%12s%10s%12sn", "Nbr", "Payment", "Principal", "Interest", "Balance");  
    printf("%4s%10s%12s%10s%12sn", "---", "-------", "---------",   
"--------", "-------");  

    pILoan->GetFirstPmtDistribution(payment, &Balance, &Principal, &Interest, &MorePmts);  

    for (short PmtNbr = 1; MorePmts; PmtNbr++)   
      
        printf("%4i%10.2f%12.2f%10.2f%12.2fn",  
        PmtNbr, payment, Principal, Interest, Balance);  

        pILoan->GetNextPmtDistribution(payment, &Balance, &Principal, &Interest, &MorePmts);   
      

    CoUninitialize();  
    return 0;  

PInvoke utiliza el mecanismo de enlace dinámico para incorporar código externo al proceso de ejecución. Las bibliotecas de vinculación dinámica (DLL) deben tener la misma arquitectura de destino que la aplicación de llamada, por lo que no es posible realizar llamadas cruzadas de 64 bits a 32 bits o viceversa. En su lugar, la DLL se asigna al espacio de direcciones de la persona que llama y se ejecuta en proceso.

COM, DCOM, COM + y ActiveX se basan en bibliotecas de comunicaciones entre procesos, pero a veces pueden convertirse en una simple carga de DLL. Los objetos vinculados a COM están relacionados, pero no son idénticos a los objetos CORBA, pero aunque CORBA desarrolló su propio localizador de objetos, la implementación COM todavía se basa libremente en las bibliotecas RPC y XDR de Sun Microsystems con extensiones para las características orientadas a objetos de COM. Los objetos COM no son referenciados por DLL, sino por un GUID que se usa para buscar la clase de objeto y consultar sus interfaces. El código objeto generalmente se ejecuta en un proceso separado y posiblemente en un servidor separado.

Más adelante puedes encontrar las críticas de otros gestores de proyectos, tú todavía eres capaz mostrar el tuyo si lo crees conveniente.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *