Mentre Lain mi ha battuto a scrivere un esempio, vi posterò che comunque nel caso in cui ...
Il processo di scrittura un wrapper per accedere la propria libreria è uguale all'accesso a una delle librerie .Net standard.
Esempio C# codice di classe in un progetto chiamato 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);
}
}
}
Si potrebbe creare un progetto di libreria di classi C++ gestito (esempio è CsharpWrapper) e aggiungere il progetto C# come un riferimento ad esso. Per utilizzare lo stesso file di intestazione per uso interno e nel progetto di riferimento, è necessario un modo per utilizzare il declspec giusto. Questo può essere fatto definendo una direttiva preprocessore (CSHARPWRAPPER_EXPORTS
in questo caso) e usando un #ifdef
per impostare la macro di esportazione nell'interfaccia C/C++ in un file di intestazione. Il file di intestazione dell'interfaccia non gestito deve contenere elementi non gestiti (o essere filtrato dal preprocessore).
di file non gestito C++ Interface Header (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);
Quindi è possibile creare un file di intestazione interno per poter includere nei file di libreria gestiti. Ciò aggiungerà le istruzioni using namespace
e può includere le funzioni di supporto di cui hai bisogno.
Managed C++ file di interfaccia di intestazione (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;
}
Poi basta scrivere il codice di interfaccia che fa l'involucro.
file di Managed C++ Interface Source (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());
}
Poi basta includere l'intestazione non gestito nel progetto non gestito, dire al linker di utilizzare il file lib generato durante il collegamento, e assicurarsi che il .Net e wrapper DLL si trovano nella stessa cartella dell'applicazione non gestita.
#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());
}
Quanto è complicata l'interfaccia che si desidera esporre a C/C++ non gestito? – CuppM
Vedere questo link per una simile domanda/risposta: http://stackoverflow.com/questions/13293888/how-to-call-ac-sharp-library-from-native-c-using-c-cli-and-ijw . – amalgamate