Laden...

C++ unter C#

Erstellt von M.Friedel vor 18 Jahren Letzter Beitrag vor 18 Jahren 9.346 Views
M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren
C++ unter C#

Hallo.

Ich studiere Informatik und bin gerade in meinem 1.Praxissemester in einer Firma.
Hier darf ich zum ersten Mal mit C# arbeiten.
Hier meine Problem.

Die Softwareentwickler arbeiten mit VB6.0 und haben bisher alles in C++
geschrieben. Jetzt habe ich die Aufgabe herauszufinden ob es möglich ist
diese 2000 Zeilen Code mit vielen Klassen die sie schon in C++ geschrieben haben unter C# verwenden können.
Mein Chef hat gemeint am liebsten würde er es mit einer .dll Datei gemacht haben.
Ist das möglich? Was hab ich für Alternativen?
Sollte denen schnellstens einen Weg aufzeigen können.

Schonmal Danke

Markus

M
456 Beiträge seit 2004
vor 18 Jahren

Ja, du kannst C++ unter C# benutzen. Dafür musst du aber einen Wrapper In C schreiben und mit DllImport einbinden.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemRuntimeInteropServicesDllImportAttributeClassTopic.asp

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Original von M.Friedel
Die Softwareentwickler arbeiten mit VB6.0 und haben bisher alles in C++
geschrieben.
Markus

??? VB oder C++?

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

unter c++ sorry.

p.s wow schnelle antwort

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Hab mir diesen link schon einige male durchgelesen und bin aber in schlau daraus
geworden. Hab ich das richtig verstanden, das ich alle meine Klassen unter
C++ ändern muss um von C# darauf zugreifen zu können?

S
8.746 Beiträge seit 2005
vor 18 Jahren

Also, C-Klassen kann man in DLLs packen. Das sind dann aber eben C-Dlls, die auch nur von C++ aus zu nutzen sind.

Dann gibt es noch normale Dlls. Die enthalten keine Klassen sondern nur Funktionen. Diese Funktion kann man mit (fast) jeder Programmeirsprache schreiben, natürlich auch mit C++. Solche Dlls kannst du mit wenig Aufwand in C# einbinden und benutzen.

Um Dlls mit Klassen für andere Sprache verfügbar zu machen, muss sie in ein COM-Objekt "verpacken". Alternativ kann man versuchen eine weitere DLL zu schreiben, welche die Klassen-DLL einbindet und aus dem objektorientieren Interface ein prozedurales Interfaces macht.

Die eigentlich Frage lautet jetzt: Wie genau sehen deine Dlls aus? Wie sind die aufgebaut? Dass sie mit C++ geschrieben wurden, sag allein noch nichts aus.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Im Grunde geht es darum soviel Code wie möglich aus C++
in C# zu verwenden. wir wollen das ganze program aber nicht
nochmal unter C# schreiben.
Lieg ich da richtig wenn ich sage aus meinem C++ Code der ja noch unmanaged
ist muss ich erstmal managed Code(/CLR) machen, um ihn dann weiter
benutzen zu können?

Danke für die Hilfe.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Wenn du deinen Alt-Code in Form von Dlls vorliegen hast, dann gilt das gesagte von oben. Oder hast du nur Soruce-Code oder C++-Libs?

Q
992 Beiträge seit 2005
vor 18 Jahren

Vielleicht wäre managed c++ auch eine alternative.
Die Klassen kannst du dann in c# verwenden, bzw. mit den richtigen Tools kannst du die auch in c# Klassen umwandeln(Z.B. Reflektor + Zusatz auf kompilierte Assembly anwenden und in C# ausgeben lassen.

Grüße Christoph

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Der Code liegt in Form von 4 .ccp Dateien
und 2 .h Dateien vor. Also nichts mit .lib.

Zum thema umwandeln von Quallo:
Was für ein Tool? Was ist ein Reflektor? Hast du mir da einen Link?

Q
992 Beiträge seit 2005
vor 18 Jahren
M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Ok hab mir das toll heruntergeladen.
So wie ich es sehe kann man da die ganzen
abhängigkeiten sehen. und wie mache ich jetzt damit weiter?
Entschuldigt mich aber ich hab wirlkich kaum Ahnung
von dem Thema, bin erst 9 Tage dabei.

Q
992 Beiträge seit 2005
vor 18 Jahren

Original von Quallo
Vielleicht wäre managed c++ auch eine alternative.
Die Klassen kannst du dann in c# verwenden, bzw. mit den richtigen Tools kannst du die auch in c# Klassen umwandeln(Z.B. Reflektor + Zusatz auf kompilierte Assembly anwenden und in C# ausgeben lassen.

Grüße Christoph

Erst in managed c++ umwandeln(das kann ganz schön viel arbeit werden, habe ich persönlich auch noch nicht gemacht), dann kann man die Klassen in C# verwenden oder die kompilierten Klassen mittels Reflector in C# Quellcode umwandeln.

M
456 Beiträge seit 2004
vor 18 Jahren

Wenn die Schnittstelle zur Bibliothek nicht sehr groß ist (2-3 Klassen mit wenigen Methoden), dann ist wrappen mit C vielleicht sinnvoller. Vorallem musst du die C++ Bibliothek nicht nach managed C++ ändern.

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

F
10.010 Beiträge seit 2004
vor 18 Jahren

Ich weis ja nicht, was da komplexes in den Klassen steht,
aber 2000 Zeilen schreibe ich dir schneller in C# nach, als diese Diskusion
gedauert hat.

Auch geht in .NET vieles einfacher als in C++.

Nur wenn Du mit echtzeit arbeitest, oder auf treiber ebene dann bleib bei C++.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Ok, dann kann ich mit dem Reflector den Code also auch umwandeln.
Ich war der meinung managed Code zu erstellen wäre recht einfach
wenn ich die MSDN Hilfe richtig verstanden habe.
c++ Code unter .Net mit den /CLR Optionen compilieren.

Es sind sehr viele Klassen mit noch viel mehr Methoden.
Also kann ich wohl einen Wrapper ausschliessen?

Das mit den 2000 Zeilen ist ja nur die Spitze vom Eisberg,
ich soll das ganze vorbereiten und nach Wegen und Lösungen suchen
damit u.U noch mehr übernommen werden kann.

Q
992 Beiträge seit 2005
vor 18 Jahren

Man sollte dann aber wenn möglich auch die Klassenbibliothek von .NET nutzen.
Zumindest bei Weiterentwicklungen.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Also dann eher versuchen einzelne Teile nach
managed Code zu bekommen?

Hätte nicht gedacht das es so ein gewichtiges Thema sein könnte.

Naja aufgeben gibt es nicht.

F
10.010 Beiträge seit 2004
vor 18 Jahren

Wie ich oben schon sagte geht in .NET vieles einfacher als in C++.

Deshalb ist es definitiv besser einen Schnitt zu machen.
Aber es ist natürlich auch möglich die Klassen einfach mit /CLR zu kompilieren,
aber das geht nicht bei allen sachen.
Das kann für eine übergangszeit OK sein, sollte aber schnellstmöglich
dann behoben werden.
Es ist auch nicht damit getan, nur die Syntax zu ändern.
Meist muss die gesammte Logik geändert werden.

Dann steht unter FW 1.1 die STL nicht zur Verfügung
( Templates/generics kommen erst mit FW 2.0 ).
Mehrfachvererbung ist tabu und vieles mehr.

Aber ehrlich gesagt finde ich MC++ so grauselig...
Die Managed Extensions sind so bescheiden eingebaut/angeflanscht,
das einem beim Lesen von Source schlecht wird.

Das hat grösstenteils nichts mehr mit C++ zu tun, und einfacher wurde es auch nicht.

Auch wirst Du als C++ entwickler ständig "verführt" in die alte Denke
zurückzufallen.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Also so langsam bin ich auch der Meinung
das ganze Projekt in der "Ganz oder garnicht" Manier
zu verfassen. Ich glaube auch das es mehr Aufwand ist
den alten C++Code so zu gestallten damit man ihn unter
C# zum laufen bekommt als das ganze in C# neu zu verfassen.
Ich lasse mich auch weiterhin gern eines Besseren belehren.

F
10.010 Beiträge seit 2004
vor 18 Jahren

Ich helfe seit Jahren Firmen beim Umstieg auf .NET.

Am "einfachsten" geht es mit VB6. Da erstellt man zur Not COM-Komponenten,
und einiges lässt sich mit den Assistenten "portieren".

C++ ist aus verschiedenen gründen deutlich schwieriger.

1.
Natürlich die o.a. Gründe.

2.
Und das ist jetzt nur eine persönliche Empfindung:
Unter C++ Entwicklern gibt es immer noch die Meinung,
das C++ die einzige echte Sprache für Männer ist.
Java ist schon Teufelswerk, aber C# ist ja so nah an VB.NET das
das bestimmt genauso ein "Kinderkram" ist.

Wenn ich dann diesen "Männern" zeige wie schnell ich eine Businessanwendung
unter C#/VB.NET schreibe, die etwas produktives macht, werden sie schon ruhiger.
Wenn dann UnitTests mit NUnit und Testrunner dazukommen, wird es schnell still.

Es gibt unbestritten Bereiche der SW-Entwicklung die weiterhin
fest in der Hand von C/C++ bleiben wird, aber das sind nur kleine Bereiche.

Deshalb, nimm Dir Zeit C# mal näher kennenzulernen.

Aus welchem Bereich kommt deine Firma?
Vielleicht hift es ja, wenn Du mal ein kleines Projekt in C# machst,
um zu zeigen wie schnell da einiges geht, und vorallem wie einfach.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Wir haben hier auch erhebliche Mengen von C++-Legacy-Code. In der Regel schreiben wir C-Wrapper, weil der Aufwand für Neuentwicklung ziemlich hoch wäre. Manchmal setzen wir auch COm ein, aber eher selten weil das Deployment zu lästig ist.

Letztlich ist es ja nur eine Frage der Kosten. Dabei sollte man eben nicht vergessen, dass auch ein C#-Code nicht gleich fehlerfrei und robust ist. Jede Entscheidung muss im Einzelfall getroffen werden.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Ich würde sagen das C# es mir schon sehr angetan hat und
ich diese Sprache unbedingt beherrschen will.

Wir sind eine Firma aus der Industrie die in der Mess- und Regeltechnik
zuhause ist. Ist ein Program zu auslesen und schreiben von Datensätzen.

Noch eine Frage zu den Com-komponenten:
Habe gelesen das die interaktionen von C# und diesen recht gut
und vorallem einfach durchzuführen sind. gibt es diese auch unter C++?

M
456 Beiträge seit 2004
vor 18 Jahren

Die Macher von Qt# hatten ähnliche Probleme:

http://qtcsharp.sourceforge.net/background.php

Sie erzeugen automatisch mit Perl einen Wrapper für C#.
Aber ich glaube nicht, dass du selbst so einen Generator bauen willst. Vorallem wenn man die vielen syntaktischen Besonderheiten von C++ berücksichtigen muss.

Das Problem ist, dass im C++ Standard nie festgelegt wurde, wie Klasseninformationen in Biblitheken abgelegt werden. Damit ist es fast unmöglich C++ Klassen in andere Programmiersprache einzubinden. Jeder Compiler-Hersteller kocht hier eigenes Süppchen.

Die Wahrscheinlichkeit ist aber hoch, dass eine Neuimplementierung deiner Bibliothek mit einem Bruchteil des ursprünglichen Codes auskommt.
Darf ich fragen was die Bibliothek eigentlich genau macht - natürlich nur, wenn es kein Geheimnis ist 😉 ?
Die Leute hier können dir sicher Hinweise geben, wie du die Funktionalität schnell nachbauen kannst.

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Das ist auch das Argument meiner Vorgesetzten.
Deshalb wollen sie die schon ziemlich ausgereiften Sourcen verwenden.

Mit Wrapper greife ich ja auf die einzelnen Funktionen zu die ich zuvor
in meinem Quellcode geändert habe?
Warum ist COM lässtig?
Was ist Deployment?

M
456 Beiträge seit 2004
vor 18 Jahren

Wenn man schon mal versucht hat ein COM-Objekt in C++ zu schreiben, dann ist das oft mit ziemlich viel Aufwand verbunden. Außerdem müssem COM Objekte korrekt bei der Installation registriert werden.

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

2.921 Beiträge seit 2005
vor 18 Jahren

Halt! Das geht, ich stand schon mal vor dem genau gleichen Problem, nur ging es darum, verschiedene C++ Compiler miteinandern zu verknüpfen, Sybase und Power++

Das einzige was Du machen musst, sind Funktions-Wrapper in C (nicht C++) für die Klassen in C++, wenn Du dann die Funktionen alle exportierst, kannst Du sie ohne Probleme in C# verwenden.

Achtung: Dazu sind viele Programmierkenntnisse vonnöten. Aber wenn man weiß wie ganz einfach.

Ungefähre Anleitung für folgendes angenommene Projekt:

Wir haben eine Klasse PhoneBook in C++.
Diese enthält folgende Funktionen:

char* SearchEntry(char* chPredial);
PhoneBookEntries* GetEntries();


//C++-DLL
//Objekt anlegen in C++ DLL
PhoneBook phoneBook = new PhoneBook();

//hier dann die Funktionswrapper zum exportieren
char* SearchEntry(char* chPredial)
{
   return phoneBook.SearchEntry(chPredial);
}

PhoneBookEntries* GetEntries()
{
   return phoneBook.GetEntries();
}

Diese Funktionen zusätzlich in der DEF Datei als dllexport definieren.

_declspec dllexport Funktionsname verwenden.

Achtung: die erste Funktion wird ohne Probleme gelingen, weil sie einen char* als Rückgabe und als Eingabe hat. Das sind dann in C# strings.

Aber PhoneBookEntries* ist ein selbst geschriebener Typ, entweder runterbrechen auf einen in C# bekannten (das sind einfach alle ansi-c-Typen wie z.B. int, short, long, char usw.) oder in C# selbst nachdefinieren.

Soweit so klar?! Oder habe ich jetzt alle Klarheiten beseitigt?

Das ist alles von der C++-Seite her.

in C# musst die die Funktionen, um sie verwenden zu können als DLL-Import definieren:

(DllImport("diecplusplusdllwodieklassendeinerfirmadrinsind.dll")]
string SearchEntry(string);

Das geht!

Achtung: wenn Sie so etwas spezielles wie Callbacks für Hooks benutzen, könnte es an dieser Stelle ein Problem geben, ebenso bei CPL-Exe-Files (die Dinger in der Systemsteuerung), ansonsten weiß ich keine nennenswerten Probleme.

Ist natürlich immer noch ein gewisser Aufwand.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

F
10.010 Beiträge seit 2004
vor 18 Jahren

Mess und Regeltechnik, habe ich befürchtet 😉

Da kann es sein, das ihr nicht um Teile in C++ herumkommt.
Ich komme aus dem Bereich Messgeräte für Nachrichtentechnik,
ich weis wie schwer Echtzeit unter Windows ist.

Unter .NET ist das fast garnicht zu händeln.
Wir haben dann einen Service geschrieben ( in C++ ) für den Echtzeitpart.

Die Oberfläche ist dann in C# geschrieben worden.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Zu dr4g0n76:

Ja das mit _declspec dllexport Funktionsname verwenden hab ich
schon mitbekommen.
Hört sich aber nach nem sehr großen Aufwand an alles neu zu überarbeiten.

Zu FZelle:

HeHeg

Das mit dem C++ und dann Oberfläche unter C#
wäre für uns vielleicht auch noch eine alternative
falls alle Stricke reißen.

Ein großes Lob an alle, sind echt super Beiträge
von euch die mich weiterbringen. Weiter so.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Hab was über Com .dll's gelesen.
Hat sich ziemlich einfach angehört für mich.
Ich mach unter C++ eine Com .dll und die kann ich dann unter
C# aufrufen.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Original von M.Friedel
Hat sich ziemlich einfach angehört für mich.

Leider doch nicht so einfach, zumindest beim ersten Mal....

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Werd trotzdem hoffen das ich es hin
bekomme.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Ich hab jetzt noch eine Frage zu Zeigern und C#.

In meiner .dll wird viel mit Zeigern gearbeitet.
Wie sieht es damit aus wegen Invoke und co?

S
8.746 Beiträge seit 2005
vor 18 Jahren

Zeiger macht man via IntPtr. Entsprechende Kopieroperation (in managed Speicher und zurück) gibt es in der Klasse Marshal. Einfach Pointer-Geschichten (ref-Entsprechung, strings und fix-length-arrays) gehen sogar vollautomtaisch.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Das hört sich jetzt bestimmt wieder einfacher
an als das es wirklich ist?

Muss also nichts mit unsafe Code machen oder?

S
8.746 Beiträge seit 2005
vor 18 Jahren

Nein, unsafe Code brauchst du dazu nicht.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Das wäre ja wirklich gut.
Wenn ich dann in meinen Arrays arbeiten kann und
auf meinen Char.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Das Stichwort zum Thema heisst "Marshalling" und bezeichnet den Übergang von Daten von managed in unmanaged Speicher und zurück. In .NET gibts viele Automatismen, einiges muss man aber per Hand machen (z.B. Arrays umkopieren, wobei die Länge als Parameter mitkommt (no-fix-length)). Über MarshalAs-Attribute kann man gezielt Datenformate aussteuern.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Danke.
Konnte nicht überzeugen. 😦
Werd für mich aber C# genauer anschauen.
Danke nochmal an alle.
Waren schöne Lösungen dabei.

MfG

Markus Friedel

A
21 Beiträge seit 2005
vor 18 Jahren

Reflector
da kannst du dir den Code übersetzen lassen.
von c# in c++ , delphi etc.

M
456 Beiträge seit 2004
vor 18 Jahren

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Danke. Sieht mir aber bisschen kompliziert aus,
oder täusche ich mich da?

F
10.010 Beiträge seit 2004
vor 18 Jahren

Klar ist das komplex, du willst ja auch ein komplexes Thema bearbeiten 😉

Ist aber nicht wirklich so schwer wie Du es Dir vorstellst.

Du kannst Du Dir ja mal auf www.pinvoke.net anschauen, wie die Wrapper für
die Windows API aussehen, und daran erkennen, wie es für dich geht.

Aber das schwierigste sehe ich daran, von den Alten Denkweisen abzulassen 😉
Aber das problem haben alle umsteiger auf .NET.

M
456 Beiträge seit 2004
vor 18 Jahren

Was heißt kompliziert. SWIG generiert automatisch Wrapper für beliebige Zielsprachen und ist damit sicher einfacher zu nutzen, als alles von Hand zu wrappen.

Das man damit auch sehr umfangreiche C++ Projekte wrappen kann, zeigt OgreDotNET:
http://www.ogre3d.org/wiki/index.php/OgreNet

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

M
M.Friedel Themenstarter:in
113 Beiträge seit 2005
vor 18 Jahren

Ja die Alte Denkweise wird es sein, die einem am
anfang so manchen Stein in den Weg legt.