Podczas lain pokonać mnie do pisania przykład, wyślę go zresztą na wszelki wypadek ...
trakcie pisania otoki dostępu do własnej biblioteki jest taki sam jak dostęp do jednej ze standardowych bibliotek .Net.
Przykład kodu C# klasa w projekcie o nazwie 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);
}
}
}
by utworzyć Managed C++ projektu biblioteki klasy (przykładem jest CsharpWrapper) i dodać swój projekt C# jako odniesienie do niego. Aby użyć tego samego pliku nagłówkowego do użytku wewnętrznego i projektu referencyjnego, potrzebny jest sposób użycia odpowiedniego declspec. Można to zrobić, definiując w tym przypadku dyrektywę preprocesora (CSHARPWRAPPER_EXPORTS
) i używając #ifdef
, aby ustawić makro eksportu w interfejsie C/C++ w pliku nagłówkowym. Plik nagłówka niezarządzanego interfejsu musi zawierać niezarządzane pliki (lub je odfiltrować przez preprocesor).
Niezarządzany plik nagłówkowy interfejsu C++ (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);
Następnie można utworzyć wewnętrzny plik nagłówkowy, aby można go było umieścić w zarządzanych plikach biblioteki. Spowoduje to dodanie instrukcji using namespace
i może zawierać potrzebne funkcje pomocnicze.
Managed C++ Interfejs plik nagłówka (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;
}
Następnie wystarczy napisać kod interfejsu, który nie opakowanie.
Managed C++ Interfejs plik źródłowy (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());
}
Wtedy właśnie obejmują niezarządzanej nagłówek w swojej niekontrolowana projektu, powiedz łącznik korzystania z wygenerowanego pliku .lib podczas łączenia, i upewnij się, Pliki .Net i opakowujące biblioteki DLL znajdują się w tym samym folderze, co niezarządzana aplikacja.
#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());
}
Jak skomplikowany jest interfejs, który chcesz eksponować na niezarządzanego C/C++? – CuppM
Zobacz ten link dla podobnego pytania/odpowiedzi: http://stackoverflow.com/questions/13293888/how-to-call-ac-sharp-library-from-native-c-using-c-cli-and-ijw . – amalgamate