2008-09-15 7 views
5

Ich habe eine Schnittstelle, die ich in C++ definiert habe, die jetzt in C# implementiert werden muss. Was ist der beste Weg, dies zu tun? Ich möchte COM in meiner Schnittstellendefinition überhaupt nicht verwenden. Die Art, wie ich das jetzt gelöst habe, besteht darin, zwei Interface-Definitionen zu haben, eine in C++ und eine in C#. Ich exponiere dann die C# -Schnittstellen als einen COM-Server. Dies war meine Anwendung, die in C++ geschrieben ist und in C# aufrufen kann. Kann ich sowieso vermeiden, meine Implementierung in C++ und C# definieren zu müssen?Definieren Sie eine Schnittstelle in C++, die in C# und C++ implementiert werden muss

Antwort

3

Wenn Sie C++/CLI anstelle von C# für Ihren verwalteten Code verwenden möchten, können Sie die native C++ - Schnittstellendefinition direkt über die Headerdatei verwenden. Wie einfach das ist, wird auf genau abhängen, was in Ihrer Schnittstelle ist - einfachsten Fall ist etwas, das Sie von C. verwenden könnte

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

+0

Fügen Sie auch hier, dass C++/CLI in Aktion von Nishant Sivakumar ist eine großartige Ressource zu verstehen, wie Sie C++ zu C# verbinden. – Juba

1

Warum möchten Sie nicht COM verwenden?

Das wäre mein Vorschlag gewesen. COM-Interop hat wirklich gut für mich funktioniert, und ich habe COM-Objekte und Schnittstellen in C# verwendet (verweisen Sie einfach auf das COM-Objekt und der Runtime Callable Wrapper wird automatisch erstellt). Ähnliches gilt auch für die Kennzeichnung einer C# -Klasse als "Register für COM-Interop".

1

Schreiben Sie die Schnittstelle in C++ und verwenden Sie Makros, um es wie eine Standard-cpp-Header-Datei unter UNIX und wie eine IDL-Datei unter Windows aussehen zu lassen (Wenn das nicht klappt, können Sie immer ein Python/Ruby-Skript schreiben die IDL aus der C++ - Header-Datei).

Kompilieren Sie die IDL, um eine Typelib zu generieren. Verwenden Sie TypeLib Importer, um die Schnittstellendefinitionen für C# zu generieren, und implementieren Sie die Schnittstellen dort.

1

Schreiben Sie die Schnittstelle in IDL und verwenden Sie ein Tool, um die Schnittstelle zur Zielsprache zu kompilieren. Sie könnten Hinweise dafür finden, wenn Sie CORBA betrachten, das sich mit sprachübergreifenden Schnittstellen beschäftigt.

/Allan

0

Sie erwähnen nicht, welche Version von .NET Sie verwenden, sondern etwas, das für mich in mit Visual Studio .NET 2003 gearbeitet hat, ist einen dünnen C# Wrapper um die pimpled Umsetzung zur Verfügung zu stellen die reale C++ Klasse:

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

private: 
    MyClass __nogc *native_ptr_; 
}; 

Offensichtlich würde man es vorziehen, eine Boost-shared_ptr zu verwenden, aber ich konnte sie nie

Methoden gut mit V.NET 2003 ... zu spielen bekommen einfach uns auf die zugrundeliegende C++ - Methoden durch den Zeiger. Methodenargumente müssen möglicherweise konvertiert werden. Um beispielsweise eine C++ - Methode aufzurufen, die eine Zeichenfolge verwendet, sollte die C# -Methode wahrscheinlich eine System.String-Zeichenfolge (System :: String in Managed C++) enthalten. Sie müssten dazu System :: Runtime :: InteropServices :: Marshal :: StringToHGlobalAnsi() verwenden.

Eine nette Sache über diesen Ansatz ist, weil Managed C++ eine .NET-Sprache ist, Sie Zugriffsmethoden als Eigenschaften (__property) verfügbar machen. Sie können sogar Attribute anzeigen, ähnlich wie in C#.

1

Der andere Ansatz besteht darin, eine "flache" API im C-Stil zu verwenden. Sie können auch extern "C" verwenden, um eine versehentliche Überlastung zu verhindern. Verwenden Sie eine DEF-Datei, um die exportierten Funktionen explizit zu benennen, sodass sie auf keinen Fall verziert sind (C++ - Funktionen werden mit einer Codierung der Parametertypen in der Exporttabelle dekoriert).

Achten Sie auf x86 auf Aufrufkonventionen. Es ist wahrscheinlich, die Verwendung von __stdcall oder __cdecl explizit zu deklarieren. Da P/Invoke hauptsächlich zum Aufrufen von Windows-APIs verwendet wird, wird standardmäßig StdCall verwendet, C und C++ jedoch standardmäßig auf Cdecl, da dies varargs unterstützt.

Ich habe vor kurzem die COM-Schnittstelle IRapiStream in eine flache C-Schnittstelle gewickelt, da .NET anscheinend versuchte, den IStream in einen Speicher zu konvertieren, der mit dem Fehler STG_E_UNIMPLEMENTEDFUNCTION fehlschlug.

2

ist ein großartiges Werkzeug zum Einbinden von C++ - Klassen in anderen Sprachen wie C#.