Mientras Lain me pegaba a escribir un ejemplo, voy a publicar de todos modos por si acaso ...
El proceso de escribir un derivador para acceder a su propia biblioteca es lo mismo que acceder a una de las bibliotecas .Net estándar.
Ejemplo C# código de clase en un proyecto llamado CsharpProject:
using System;
namespace CsharpProject {
public class CsharpClass {
public string Name { get; set; }
public int Value { get; set; }
public string GetDisplayString() {
return string.Format("{0}: {1}", this.Name, this.Value);
}
}
}
Para ello se crea un proyecto de biblioteca de clases C++ administrada (ejemplo es CsharpWrapper) y añadir su proyecto de C# como una referencia a él. Para usar el mismo archivo de encabezado para uso interno y en el proyecto de referencia, necesita una forma de usar la declspec correcta. Esto se puede hacer definiendo una directiva de preprocesador (CSHARPWRAPPER_EXPORTS
en este caso) y usando un #ifdef
para establecer la macro de exportación en su interfaz C/C++ en un archivo de encabezado. El archivo de encabezado de interfaz no administrado debe contener elementos no administrados (o debe haberlos filtrado por el preprocesador).
Archivo de encabezado de interfaz C++ no administrado (CppInterface.h):
#pragma once
#include <string>
// Sets the interface function's decoration as export or import
#ifdef CSHARPWRAPPER_EXPORTS
#define EXPORT_SPEC __declspec(dllexport)
#else
#define EXPORT_SPEC __declspec(dllimport)
#endif
// Unmanaged interface functions must use all unmanaged types
EXPORT_SPEC std::string GetDisplayString(const char * pName, int iValue);
continuación, puede crear un archivo de encabezado interno para poder incluir en sus archivos de biblioteca administrados. Esto agregará las declaraciones using namespace
y puede incluir las funciones auxiliares que necesite.
archivo de C++ Header interfaz (CsharpInterface.h):
#pragma once
#include <string>
// .Net System Namespaces
using namespace System;
using namespace System::Runtime::InteropServices;
// C# Projects
using namespace CsharpProject;
//////////////////////////////////////////////////
// String Conversion Functions
inline
String^ToManagedString(const char * pString) {
return Marshal::PtrToStringAnsi(IntPtr((char *) pString));
}
inline
const std::string ToStdString(String^strString) {
IntPtr ptrString = IntPtr::Zero;
std::string strStdString;
try {
ptrString = Marshal::StringToHGlobalAnsi(strString);
strStdString = (char *) ptrString.ToPointer();
}
finally {
if (ptrString != IntPtr::Zero) {
Marshal::FreeHGlobal(ptrString);
}
}
return strStdString;
}
A continuación, sólo escribir el código de interfaz que hace la envoltura.
Gestionado archivo C++ Source Interface (CppInterface.cpp):
#include "CppInterface.h"
#include "CsharpInterface.h"
std::string GetDisplayString(const char * pName, int iValue) {
CsharpClass^oCsharpObject = gcnew CsharpClass();
oCsharpObject->Name = ToManagedString(pName);
oCsharpObject->Value = iValue;
return ToStdString(oCsharpObject->GetDisplayString());
}
A continuación, sólo incluyen la cabecera no administrado en su proyecto no administrado, decirle al enlazador a utilizar el archivo .lib generados al vincular, y asegurarse de que la Las DLL .Net y wrapper están en la misma carpeta que su aplicación no administrada.
#include <stdlib.h>
// Include the wrapper header
#include "CppInterface.h"
void main() {
// Call the unmanaged wrapper function
std::string strDisplayString = GetDisplayString("Test", 123);
// Do something with it
printf("%s\n", strDisplayString.c_str());
}
¿Cuán complicada es la interfaz que desea exponer a C/C++ no administrado? – CuppM
Vea este enlace para una pregunta/respuesta similar: http://stackoverflow.com/questions/13293888/how-to-call-ac-sharp-library-from-native-c-using-c-cli-and-ijw . – amalgamate