2010-01-19 7 views
6

¿Cómo hacer que una API nativa sea amigable con Invoice?¿Cómo hacer una API nativa amigable con Invoke?

hay algunos consejos sobre cómo modificar los programas nativos que se utilizarán con P/Invoke here. Pero antes de siquiera escribir programas nativos, ¿cuáles son las cosas que debería considerar para que mis programas/biblioteca sean amigables con PInvoke?

usando C o C++ están bien.


actualización:
si escribo una API C, ¿cuáles son las cosas que tengo que hacer para que Es P/Invoke-poder usar C# sintaxis como la siguiente:

[DLLimport("MyDLL.dll")] 

es posible hacer lo mismo con el código nativo de C++/biblioteca?


Resumen/Rephrase de algunos consejos para hacer un P/Invoke-amigable nativo API:
+ los parámetros deben ser de tipos nativos (int, char *, float, ...)
+ menos parámetros es mejor
+ si la memoria dinámica se asigna y se pasa al código administrado, asegúrese de crear una función "más limpia", que es también la p/invocarse
+ proporcionar muestras y/o pruebas de unidad que ilustran cómo llamar a la API de .NET
+ proporcionar C++/CLI wrapper

Respuesta

1

Por definición, cada función nativa se puede p/invocar desde el código administrado. Pero para ser amigable con p/invoke, una función debe tener la menor cantidad posible de parámetros, que deberían ser de tipo nativo (int, char *, float, ...). Además, si una función asigna memoria en algún puntero que se devuelve al código administrado, asegúrese de escribir su parte del contador que liberará el puntero ya que el código administrado no puede liberar la memoria asignada del código no administrado.

+0

"una función debería tener el menor número posible de parámetros que deben ser de tipos nativos (int, char *, flotador, ...)" ¿Puedo resumir en: -> los parámetros deben ser de tipos nativos (int, char *, float, ...) -> menos parámetros es mejor -> si la memoria dinámica se asigna y pasa al código administrado, asegúrese de crear una función "limpiadora" que también esté p/invocada –

+0

Sí , ese es un buen resumen. –

1

Proporcionar un ejemplo de llamar correctamente desde C# .NET o, aún mejor proporcionar una clase .NET que envuelve todas sus métodos

Escribiendo una prueba de unidad sencilla con nunit demuestra que el código funciona correctamente cuando se llama desde .Net sería una gran forma de hacerlo.

Asimismo, recuerda que los desarrolladores .NET que es probable que sean de llamar a su código es poco probable que sabe mucho acerca de C++, o no saben los tamaños de los diferentes tipos de datos, etc, o cómo estos tipos se asignan a los atributos PInvoke .

Sobre todo, piense cómo desea que se vea el código de sus clientes y luego diseñe una API que lo permita.

3

En lugar de utilizar P/Invoke, si está controlando la biblioteca nativa usted mismo, puede escribir un conjunto de clases C++/CLI que envuelven las llamadas nativas. En muchos casos, esto funcionará mejor que el uso de la invocación de plataforma, y ​​obtendrá el beneficio adicional de la corrección de tipo.Por ejemplo, si usted tiene algún tipo de API de C, como las siguientes (que no hace nada útil, me acaba de agregar punteros y estructuras para reforzar el hecho de que es código nativo):

struct SomeStruct { 
    int a, b; 
    int* somePtr; 
}; 

int foo(struct SomeStruct* a, int b) { 
    *a->somePtr = a->a + a->b; 
    return a->b * *a->somePtr + b; 
} 

Usted puede crear una clase de C++/CLI para envolverlo:

public ref class MyNativeAPI { 
    private: 
    SomeStruct* x; 
    public: 
    MyNativeAPI() { 
     x = new SomeStruct; 
    } 
    ~MyNativeAPI() { 
     delete x; 
    } 
    int Foo(int a) { 
     pin_ptr<SomeStruct*> ptr = this->x; 
     return foo(ptr, a); 
    } 
} 

a continuación, puede llamar a esto en C#:

MyNativeAPI a = new MyNativeAPI(); 
if(a.Foo(5) > 5) { ... }; 

Vas a tener que leer más en C++/CLI para entender los nuevos controles que tiene tanto sobre el manejado él ap y el montón nativo, y las advertencias para mezclar los dos (como el pin_ptr que utilicé arriba), pero en general es una solución mucho más elegante para lograr la interoperabilidad nativa en .NET.

Cuestiones relacionadas