Frage

Ich habe eine Schnittstelle, die ich in C ++ definiert haben, die jetzt in C # implementiert werden muss. Was ist der beste Weg, um dies zu realisieren? Ich will nicht, COM verwenden, überhaupt in meiner Schnittstellendefinition. Die Art, wie ich dieses Recht jetzt gelöst haben, ist zu zwei Schnittstellendefinitionen zu haben, eine in C ++ und eine in C #. Ich belichten dann das C # Schnittstellen als COM-Server. Dies war meine Anwendung, die in C ++ geschrieben ist kann in C # aufrufen. Gibt es trotzdem kann ich vermeiden, dass meine Implementierung in C ++ sowie C # definieren?

War es hilfreich?

Lösung

Wenn Sie bereit sind, C ++ / CLI für den verwalteten Code anstelle von C # zu verwenden, dann können Sie verbrauchen nur die native C ++ Interface-Definition direkt über die Header-Datei. Wie einfach dies sein wird, auf genau davon abhängen, was in Ihrer Schnittstelle ist -. Einfachsten Fall ist etwas, das Sie von C verwenden könnten

Werfen Sie einen Blick auf Marcus Heege Expert C ++ / CLI: .NET für Visual C ++ Programmierer , für viele nützliche Informationen über das Mischen native und verwaltete C ++ in .NET.

Andere Tipps

Swig ist ein großes Werkzeug für die Verpackung C ++ Klassen in anderen Sprachen wie C #.

Warum wollen Sie nicht COM benutzen?

Das wäre mein Vorschlag gewesen. COM-Interop hat wirklich gut für mich gearbeitet, und ich habe COM-Objekte und Schnittstellen in C # verwendet (einfach das COM-Objekt verweisen und die Laufzeit aufrufbare Wrapper automatisch erstellt wird). In ähnlicher Markierung eine C # Klasse als „für COM-Interop registrieren“ um die andere Art und Weise gearbeitet hat.

Schreiben Sie die Schnittstelle in C ++ und Makros verwenden, um es wie eine Standard-CPP-Header-Datei auf UNIX und wie eine IDL-Datei auf Windows aussehen (Wenn dies nicht funktioniert, können Sie immer einen Python / Ruby-Skript schreiben die erzeugen IDL aus der Headerdatei C ++).

die IDL Kompilieren eines typelib zu erzeugen. Verwenden Sie TypeLib Importeur die Schnittstellendefinitionen für C # zu generieren und implementieren, um die Schnittstellen gibt.

Schreiben Sie die Schnittstelle in IDL und ein Tool verwenden, um die Schnittstelle zu der Zielsprache zu übersetzen. Sie könnten Zeiger für diese finden, wenn sie in CORBA suchen, die mit Quer Sprache Interfacing anging.

/ Allan

Der andere Ansatz ist es, einen 'flat', C-Stil-API zu verwenden. Genauso gut könnte man extern "C" verwenden, um eine versehentliche Überlastung zu verhindern. Verwenden Sie Datei eine DEF explizit die exportierten Funktionen zu nennen, so dass sie auf jeden Fall nicht in irgendeiner Weise verziert (C ++ Funktionen sind ‚dekoriert‘ mit einer Codierung der Parametertypen in der Exporttabelle).

Auf x86, passen sie Konventionen fordern. Es ist wahrscheinlich ausdrücklich die Verwendung von __stdcall oder __cdecl zu erklären. Da P / Invoke in erster Linie verwendet wird, Windows-APIs aufrufen, wird standardmäßig StdCall, aber C und C ++ standardmäßig cdecl, denn das unterstützt varargs.

ich den COM-Schnittstelle IRapiStream in einer flachen C-Schnittstelle vor kurzem eingewickelt wie .NET versucht, schien die IStream in einen Speicher zu konvertieren, die mit dem Fehler STG_E_UNIMPLEMENTEDFUNCTION fehlgeschlagen.

Sie erwähnen nicht, welche Version von .NET Sie verwenden, sondern etwas, das du mit dem Visual Studio .NET 2003 für mich gearbeitet hat ist einen dünnen C # Wrapper um die pimpled Implementierung der realen C ++ Klasse zu bieten:

public __gc class MyClass_Net {
public:
   MyClass_Net()
      :native_ptr_(new MyClass())
   {
   }
   ~MyClass_Net()
   {
      delete native_ptr_;
   }

private:
   MyClass __nogc *native_ptr_;
};

Natürlich würde man lieber eine Boost-Shared_ptr verwenden, aber ich konnte sie nie mit V.NET 2003 ...

schön zu spielen bekommen

Methoden einfach nach vorn auf die zugrunde liegenden C ++ Methoden durch den Zeiger. Methodenargumente müssen umgewandelt werden. Um zum Beispiel eine C ++ Methode aufrufen, die einen String, sollte die C # Methode nehmen wahrscheinlich ein System.String (System :: String in Managed C ++). Du müss System :: Runtime :: InteropServices verwenden :: Marshal :: StringToHGlobalAnsi (), das zu tun.

Eine nette Sache über diesen Ansatz ist, weil Managed C ++ eine .NET-Sprache ist, erhalten Sie Accessoren als Eigenschaften (__property) zu belichten. Sie können auch Attribute aussetzen, sehr ähnlich wie in C #.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top