DLL in C geschrieben gegen die gleiche in C ++ geschrieben

8

Ich hatte heute eine Diskussion mit einem Kollegen. Er behauptete, dass das Schreiben einer DLL in C jeder anderen Anwendung, die in welcher Sprache auch immer geschrieben ist, erlauben würde, diese DLL zu verwenden. ABER, wenn diese DLL in C ++ geschrieben ist, ist die Anzahl der Anwendungen, die diese DLL verwenden könnten, begrenzt (möglicherweise aufgrund von Sprachbeschränkungen).

  1. Stimmt das, wenn er das sagt?
  2. Wenn Sie eine DLL schreiben, die von allen Arten von Anwendungen in allen möglichen Sprachen verwendet werden sollte (aber auf der gleichen Plattform; vergessen wir die Portabilität ein wenig), würden Sie es in C / C ++ schreiben und warum ?

Ich hoffe, dass diese Frage keine Gorilla vs. Shark Frage ist. Wenn es ist, bitte schließen Sie es.

    
Anish Ramaswamy 24.05.2013, 08:00
quelle

3 Antworten

11

Die meisten Sprachen bieten eine (einfache) Möglichkeit, die C-Funktion von einer DLL aus aufzurufen. Dies ist bei C ++ nicht der Fall, da C ++ ABI (die binäre Schnittstelle der C ++ - Funktion) herstellerspezifisch ist.

Hinzu kommt, dass es nahezu unmöglich ist, mit C ++ - DLLs zu kommunizieren, die erweiterte C ++ - Konstrukte wie Templating oder die STL verwenden.

Der Inhalt Ihrer DLL kann jedoch in C ++ geschrieben werden. Sie müssen nur sicherstellen, dass Ihre Schnittstelle C-konform ist. Verwenden Sie dazu keine C ++ - Konstrukte in Ihrer Oberfläche und umgeben Sie Ihre Deklarationen mit:

%Vor%

... auf diese Weise wickeln Sie Ihre C ++ - Bibliothek mit einer C-Schnittstelle.

EDIT: Wie Mats Petersson schrieb, vergessen Sie nicht, sicherzustellen, dass Sie jede mögliche C ++ - Ausnahme in Ihrem Wrapper behandeln.

    
Matthieu Rouget 24.05.2013, 08:08
quelle
4

1) Wenn die INTERFACE, die von der DLL bereitgestellt wird, tatsächlich eine C ++ - Schnittstelle ist, dann macht es es ja für andere Sprachen schwierig (wenn nicht unmöglich), mit der DLL zu kommunizieren.

C ++ ist komplexer als C, weil es eine komplexere Struktur von Klassen gibt ( this Zeiger wird weitergegeben, virtuelle Funktionszeiger / VTABLE-Layout) und Ausnahmebehandlung (wo der aufgerufene Code die Tatsache behandeln muss) dass die Ausnahme auf irgendeine Weise passiert ist, und dazu muss der Code in der Lage sein, den Call-Stack des Codes, der die Exception ausgelöst hat, "abzuwickeln" und alle auf dem Weg erstellten Objekte zu zerstören, bis ein catch gefunden wird. Wenn das nicht im Call-Stack innerhalb der DLL vorhanden ist, bekommen Sie Probleme - diese Unwinding ist nicht Teil des C ++ - Standards, da der Standard nicht einschränken will, welche Architekturen und welche Funktionen ein Prozessor zur Implementierung von C ++ benötigt mehr als nötig). Das Einfangen von Ausnahmen innerhalb der DLL wird hier Probleme lösen.

Mit anderen Worten, wenn die Sprache nicht C ++ ist [und möglicherweise vom selben Hersteller stammt], die den Code aufruft, ist es notwendig, dass C ++ mit jeder Sprache, die es aufruft, behandelt wird. Das kann ziemlich kompliziert werden.

Jedes C ++ Objekt muss aus der / in die relevante Sprache im aufrufenden Code übersetzt werden. Für grundlegende Typen, die mit C gemeinsam sind, ist dies im Allgemeinen kein Problem, aber Klassen, Strukturen usw. müssen mit etwas kompatibel sein, das in der lokalen Sprache kompatibel ist.

Auf der anderen Seite: Eine C-Funktion ist sehr einfach zu verbinden: Setzen Sie die Argumente auf den Stack, rufen Sie die Funktion auf und bereinigen Sie die Argumente bei der Rückgabe. Es passiert nichts Seltsames, keine versteckten Funktionsparameter, keine Stapelabwicklungen. Die einzige kleine Komplikation sind Funktionen, die ein struct zurückgeben (das ist größer als eine bestimmte Größe) - aber das ist ein ziemlich spezieller Fall in C. Cs "objets" sind viel einfacher, und die meisten Sprachen haben Typen, die gut zum grundlegenden C passen Sprachtypen (aber C-Stil struct kann immer noch einige interessante Probleme verursachen, und union kann eine echte Herausforderung sein, wenn es "clever" verwendet wird).

2) Das Auswählen von Sprachen ist ein komplexes Geschäft und hängt weitgehend davon ab, wie die DLL verwendet werden soll oder welche Art von Schnittstelle sie bereitstellen soll und an welche Schnittstellen sie selbst angeschlossen werden soll - wenn Ihre DLL eine Schnittstelle bildet zu einer anderen C ++ - DLL (oder einem anderen C ++ - Code), dann möchten Sie wahrscheinlich C ++ verwenden. Es gibt jedoch Möglichkeiten, eine C ++ - DLL mit einer C-Schnittstelle zu erstellen, indem Sie extern "C" für die Schnittstellenfunktionen verwenden (und sicherstellen, dass nichts throws über der Wand zu "C" liegt, da dies definitiv Probleme verursacht).

Fazit: Wenn man die Schnittstelle auf "nur C ++ verwenden" beschränkt, gibt es natürlich eine weitere Komplikation darin, dass jeder, der die Bibliothek von beispielsweise C, Python oder Lisp [die wahrscheinlich C-Funktionen ziemlich leicht aufrufen können] verwendet muss den C ++ Code in einen C-Wrapper schreiben. Und ja, das kann gemacht werden und wird ziemlich regelmäßig verwendet, wenn eine wirklich gute Bibliothek in C ++ verfügbar ist, dass jemand eine Verbindung zu einer Sprache herstellen möchte, die eine C-Stil-Schnittstelle zur Verfügung stellt. Es ist fast die gleiche Lösung wie die "C-C ++ - Schnittstelle in der DLL bereitstellen", außer es wird nicht vom Hersteller der DLL zur Verfügung gestellt.

    
Mats Petersson 24.05.2013 08:41
quelle
0

Jede Sprache hat ihre eigenen Merkmale wie Aufrufkonvention, Stack-Setup und andere Dinge. Wann immer Sie versuchen, mit Funktionsaufrufen umzugehen, die Sprachgrenzen überschreiten, müssen Sie damit umgehen. Compiler unterstützen in der Regel eine Vielzahl von Aufrufkonventionen. Sie müssen also sicherstellen, dass die Definitionen und die Kompilierung korrekt sind, und dann können Sie jede Sprache verwenden, um mit Modulen von anderen zu kommunizieren. Die Aussage als solche, dass es einfacher oder schwerer ist, aus der einen oder anderen Sprache als solcher zu tun, ist nicht wahr, weil man sich irgendwann immer damit auseinandersetzen muss.

Ich wähle die Sprache aus, die mir am besten zu meiner Aufgabe passt, nicht umgekehrt. Wenn ich GUI-Apps schreibe, verwende ich normalerweise Java, weil ich mich so auf die Lösung konzentrieren kann, anstatt den Speicher zu verfolgen. :) Wenn ich Leistung möchte, verwende ich C oder C ++ oder sogar Assembler, also hängt die Wahl der Sprache davon ab, was ich damit machen will oder wie meine Umgebung aussieht.

    
Devolus 24.05.2013 08:07
quelle

Tags und Links