En mi aplicación C#, me gustaría escribir una parte del código en C. Tengo la intención de escribir una DLL que podría ser interoperable con .Net. ¿Cómo puedo hacer eso?Escribir una DLL en C/C++ para la interoperabilidad .Net
Respuesta
Fundamentalmente, hay tres formas correctas de hacerlo:
- Utilice C++/CLI. Esta es la forma óptima si esta DLL va a ser utilizada solo por .NET.
- Utilice una API compatible con "
extern "C"
", como la API de Windows. Este es el más portátil, pero no es tan conveniente para quienes llaman como el uso de un modelo de clase para representar sus objetos.- Esta es la mejor opción si realmente desea escribir en ANSI C (no en C++).
- Por este camino, usted escribe sus funciones como
extern "C" returntype __stdcall __declspec(dllexport) func(params) { ... }
- También debe utilizar un modelo de memoria "Caller-ofrece-el-buffer", en lugar de devolver un búfer asignado dentro de su biblioteca. En los casos en que necesita asignar memoria para el estado interno, la persona que llama debe verlo como un identificador opaco y debe proporcionar funciones de acceso para que la persona que llama pueda extraer datos. Bajo ninguna circunstancia se debe esperar que la persona que llama desasigne la memoria asignada dentro de su biblioteca, sin embargo, está bien que la persona que llama pida a la biblioteca que realice la desasignación.
- Use COM o una API tipo COM. Aquí regresa (a menudo a través de un parámetro) un puntero a una interfaz, que es una clase con funciones virtuales puras, sin funciones no virtuales y sin datos.
- La implementación está en clases concretas derivadas de esta interfaz abstracta, pueden tener datos y funciones auxiliares en abundancia, ya que eso no afecta a la interfaz binaria.
- Esto es mucho más trabajo en la biblioteca pero extremadamente portátil y fácil de usar para el consumidor.
Y hay una cosa que absolutamente no se debe hacer:
- uso
__declspec(dllexport)
en clases de C++.
EDIT: también quiero explicar algunas buenas prácticas para la opción n. ° 2, que maximizará la portabilidad y hará que las partes nativas de C/C++ se puedan utilizar también desde aplicaciones no administradas.
Usted puede hacer que más fácil con una macro, la forma habitual de hacerlo es:
En el archivo de cabecera, todas las declaraciones de funciones parecen
MYPROJECTAPI(returntype) PublicFunc(params);
En su proyecto, la definición es
#define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllexport)
En los proyectos de consumo
#define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllimport)
y luego puede definir la macro de manera diferente para otros compiladores como gcc que no usan __declspec
.
La solución completa se vería así (en el archivo de cabecera pública myproject.h
):
#if _WIN32
# if BUILDMYPROJECT
# define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllexport)
# else
# define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllimport)
# endif
#else
# define MYPROJECTAPI(returntype) extern "C" returntype
#endif
y luego su proyecto de Visual C++ causaría BUILDMYPROJECT
que definirse en la construcción de MyProject.dll
A través de la capa P/Invoke.
Esto no ayuda con el proceso de escritura de DLL * en absoluto *, que es de lo que se trata la pregunta. –
Ok. Tengo entendido que estaba pidiendo una forma de comunicarse con C/C++ dll desde .NET. La capa P/Invoke funciona. – Adi
La forma en que analizo la pregunta es "¿Cómo hago eso [escribir una DLL que sería interoperable]?" –
En pocas palabras:
(1) Crear un nuevo proyecto de biblioteca de C++/CLI.
(2) Escriba su código. Para las clases que necesitan ser accesible desde su proyecto de C#, asegúrese de crearlas como clases CLR:
public ref class R {/*...*/}; // CLR class
public value class V {/*...*/}; // CLR struct
public interface class I {/*...*/}; // CLR interface
(3) Compilar el proyecto y añadir una referencia a él en su proyecto de C#.
¿cómo se puede crear un proyecto de biblioteca C++/CLI con visual studio 2010? –
@tinmaru: no tengo VS 2010 instalado ahora, pero de acuerdo con MSDN (http://msdn.microsoft.com/en-us/library/0fyc0azh.aspx), debe haber una "CLR/Class Library "plantilla de proyecto disponible. – Heinzi
A continuación se muestra un ejemplo para una aplicación donde tuve que hacer precisamente eso. En mi caso, necesitaba una DLL para envolver llamadas a funciones que solo estaban disponibles en .lib. La parte clave es extern "C" __declspec (dllexport)
en la declaración. Eso es básicamente todo lo que necesitas. El resto simplemente estaba usando dllimport
en la aplicación C# y obteniendo la clasificación correcta.
extern "C" __declspec (dllexport) LONG EstablishContext(DWORD dwScope,
LPCVOID pvReserved1,
LPCVOID pvReserved2,
LPSCARDCONTEXT phContext)
{
return SCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext);
}
No te olvides de '__stdcall' (o de forma equivalente, utiliza la macro' WINAPI'). Esto simplificará considerablemente las declaraciones de p/invoke. –
- 1. forma idiomática para escribir la función de interoperabilidad .NET
- 2. Fuerza la interoperabilidad de .NET para utilizar el DLL COM local
- 3. ¿Qué es el dll de interoperabilidad?
- 4. iPhone/.NET WCF Interoperabilidad
- 5. Interoperabilidad de Delphi con .NET
- 6. .NET y Lotus Notes interoperabilidad
- 7. Proceso de horquillas con CC .NET
- 8. .NET - ¿Cómo depurar una DLL?
- 9. ¿Ya existe una clase contenedora para una interoperabilidad COM IStream?
- 10. escribir un DSL para la plataforma .Net
- 11. ¿Pasar objeto VB6 al objeto .NET a través de interoperabilidad?
- 12. Problema al cerrar la aplicación excel interoperabilidad correctamente en .net
- 13. ¿Puede una DLL llamar a una DLL .NET?
- 14. ¿Herramienta para crear contenedores .NET para una DLL COM?
- 15. .Net 3.5 Dll en una aplicación .Net 4.0 cualquier problema
- 16. En .NET, ¿hay una necesidad de registrar la DLL?
- 17. Una forma de compilar la biblioteca C en .Net dll?
- 18. Interoperabilidad AES entre .Net y iPhone?
- 19. ¿Por qué se prefiere la interoperabilidad de COM sobre P/Invoke en .NET?
- 20. ¿Cree la aplicación VB6 usando una clase en una DLL, luego cambie esa DLL después de la compilación?
- 21. Registrar para interoperabilidad COM
- 22. acceder a .net2.0 DLL en un archivo DLL .NET 4.0
- 23. interoperabilidad COM sin regasm
- 24. ¿La interoperabilidad COM respeta los límites del Dominio de aplicación .NET para la carga de ensamblaje?
- 25. Fusiona varias DLL nativas en una DLL
- 26. ¿Hay disponible una biblioteca de contenedor user32.dll completa para .NET?
- 27. ¿Puedo usar una DLL .NET en "Delphi 2007 for Win32"?
- 28. ¿Cómo puedo invocar un método estático en un objeto .NET a través de la interoperabilidad COM?
- 29. Detalles de call/cc
- 30. Cargue Dll varias veces para permitir multihebras en .Net
¿cómo se puede crear un proyecto de C++/CLI con visual studio 2010? –
Archivo -> Nuevo -> Proyecto, luego Visual C++ -> CLR -> Biblioteca de clases –
No se compila. Tengo el siguiente error: error TRK0005: Error al localizar: "CL.exe". –