Ist es möglich bei Visual Studio 2010 ein C# Programm auch für Linux zu kompilieren?
-
Hallo zusammen.
Ich benutze gerade Visual Studio 2010 Ultimate und programmiere mit C#. Dabei werden immer .exe Dateien erstellt. Man erzählt sich doch das C# wie Java auch Plattformunabhängig ist aber wie genau kann ich denn ein Programm kompilieren das sowohl unter Windows als auch Linux läuft?
-
lalalala schrieb:
Man erzählt sich doch das C# wie Java auch Plattformunabhängig ist
"Wie Java"? Das hör ich zum ersten Mal. Die MS-Lesart von plattformunabhängig ist eher wie "auch auf Microsoft-Smartphones" zu verstehen...
aber wie genau kann ich denn ein Programm kompilieren das sowohl unter Windows als auch Linux läuft?
Indem du darauf achtest, dass es auch unter Mono läuft. Das bedeutet gewisse Einschränkungen, aber wenn die erfüllt sind sollte das prinzipiell gehen.
-
C# ist 100% Plattformunabhängig. C# ist schliesslich nicht mehr als ein Standard, und den kann man so-gut-wie überall implementieren.
Mit dem .NET Framework sieht es dann wieder anders aus.
-
Also ich dachte mir das so das ich das Programm zum Teil auf Windows entwickle und die Binärdatei später auch auf einem Linux System laufen lassen kann. Aber standartmäßig wird eine exe erzeugt gibt es keine Plattformunabhängige Endung wie .xyz die unter beiden System läuft wie das Beispiel bei Java .jar?
-
Terster schrieb:
Also ich dachte mir das so das ich das Programm zum Teil auf Windows entwickle und die Binärdatei später auch auf einem Linux System laufen lassen kann. Aber standartmäßig wird eine exe erzeugt gibt es keine Plattformunabhängige Endung wie .xyz die unter beiden System läuft wie das Beispiel bei Java .jar?
Die ist Plattformunabhängig. Eine *.exe oder eine *.dll ist schliesslich ein PE-Format (Protable Executable). Dieses Format ist dokumentiert. Darin befindet sich der CIL Code. Ein Programm auf Linux kann somit auch eine *.exe oder *.dll lesen und ausführen. Schliesslich ist .Net wie Java eine interpretierte Sprache.
Und wenn du nur mal kurz in die FAQ von Mono geschaut hättest, hättest du deine Frage auch gleich beantwortet gehabt:
http://www.mono-project.com/FAQ:_GeneralGrüssli
-
Dravere schrieb:
Schliesslich ist .Net wie Java eine interpretierte Sprache.
Bis zu dem Satz hat alles im Beitrag gestimmt
.Net Code wird in keinster Weise interpretiert. Er wird immer vor der Ausführung durch den JIT Compiler in nativen Code kompiliert. Bei Java ist es nen bissle uneindeutiger, in aller Regel wird da heute aber auch kaum mehr was interpretiert.
-
JIT
Natürlich werden in Java der meiste wenn nicht sogar der vollständige Byte-Code nativ kompiliert. Deswegen dauert der Erststart einer Anwendung lange, wenns aber erst läuft dann läuft es verdammt flüssig. Bestimmte Algorhitmen laufen durch den intelligenten JIT unter Java sogar schneller als einer von einem C++-Compiler generierter (ja, flamet mich zu, ist aber so)
.NET-Executables sind in der Regel auch nichts anderes als Byte-Code, nur halt eben mit einem PE-Header für das Framework.
-
Zwergli schrieb:
Dravere schrieb:
Schliesslich ist .Net wie Java eine interpretierte Sprache.
Bis zu dem Satz hat alles im Beitrag gestimmt
.Net Code wird in keinster Weise interpretiert. Er wird immer vor der Ausführung durch den JIT Compiler in nativen Code kompiliert. Bei Java ist es nen bissle uneindeutiger, in aller Regel wird da heute aber auch kaum mehr was interpretiert.
Genau.
Und wenn überhaupt, dann müsste man sagen dass die IL bzw. der Bytecode die "interpretierte Sprache" ist. Sowohl Java als auch C# werden zu 100% compiliert, ohne JIT, direkt vom Compiler.
Nur dass der Compiler dann üblicherweise keinen Maschinencode für existierende Maschinen ausspuckt, sondern die IL/den Bytecode für die jeweilige VM.
-
hustbaer schrieb:
Nur dass der Compiler dann üblicherweise keinen Maschinencode für existierende Maschinen ausspuckt, sondern die IL/den Bytecode für die jeweilige VM.
Hmm, im Falle von .NET wird der Code vor der ersten Ausführung auf der Zielmachine compiliert. Das ist gerade eine der Stärken von .NET, da der JIT aif der Zielmachine Optimierungen gezielt für CPU, Speicher etc berücksichtigen kann.
-
loks schrieb:
hustbaer schrieb:
Nur dass der Compiler dann üblicherweise keinen Maschinencode für existierende Maschinen ausspuckt, sondern die IL/den Bytecode für die jeweilige VM.
Hmm, im Falle von .NET wird der Code vor der ersten Ausführung auf der Zielmachine compiliert. Das ist gerade eine der Stärken von .NET, da der JIT aif der Zielmachine Optimierungen gezielt für CPU, Speicher etc berücksichtigen kann.
C# wird vom "normalen" Compiler vollständig nach IL übersetzt.
Der IL-Code wird dann vor der Ausführung erstmal geJITed. Vom .NET Framework. Das ist halt so, müsste aber nicht so sein.Im Falle Java z.B. gibt es CPUs, die Java-Bytecode "native" ausführen können. OK, diese CPUs übersetzen das intern natürlich erstmal in was anderes, aber das machen sie halt selbst. Genau so wie ein Pentium/Core2/Athlon/Core i/... den x86 bzw. AMD64 Code erstmal intern in was anderes übersetzt.
Sogesehen besteht zwischen Java, C# und C++ kein grundlegender Unterschied was das Thema "compiliert vs. geJITed vs. interpretiert" angeht.
-
Der JIT bei Java und .Net ist eigentlich nur ein Interpreter. Somit sind Java und .Net für mich interpretierte Sprachen. Der JIT ist für mich in dem Ganzen nur ein Optimierungstool. Man kann da auch andere Beispiele nehmen. Lua ist auch interpretiert und hat ebenfalls einen JIT mit LuaJIT. Wenn ich mich recht Erinnere gibt es ebenfalls für Python, welches eine interpretierte Sprache ist, einen JIT. Die Browser-Hersteller setzen inzwischen bei der interpretierten Sprache Javascript ebenfalls einen JIT ein.
Nichts desto trotz bleiben dies alle interpretierte Sprachen. Sie werden eben nicht direkt in Maschinensprache übersetzt. Und oft kann auch der JIT nicht alles in Maschinensprache übersetzen oder muss zur Laufzeit Dinge neu übersetzen, in dem er die entsprechenden Bereiche neu interpretiert.
Der JIT könnte man fast auf ein Cache für Maschinencode reduzieren. Ein reines Optimierungswerkzeug.
Grüssli
-
@Dravere
Diese Argumentation lässt sich genau so auf AMD64 Code anwenden.Wichtig ist IMO trotzdem noch die Unterscheidung IL <-> C#.
C# wird niemals niemals nie interpretiert.IL zwar auch nicht, aber da kann man durchaus streiten. D.h. auf IL bezogen verstehe ich deine Argumentation, auch wenn ich die Sache anders sehe.
Auf C# bezogen ist sie aber einfach nur falschEDIT
Und oft kann auch der JIT nicht alles in Maschinensprache übersetzen oder muss zur Laufzeit Dinge neu übersetzen,
Hast du ein Beispiel? Wenn selbstmodifizierender Code o.ä. erlaubt wäre, dann OK. Wenn Code zur Laufzeit neu generiert wird auch. Aber davon abgesehen fällt mir jetzt nix ein.
in dem er die entsprechenden Bereiche neu interpretiert.
Der JITer compiliert, oder wenn du willst: übersetzt. Er interpretiert aber schonmal sicher nix. Also bei .NET. Bei Java weiss ich nicht, ich glaube da gab's mal Implementierungen die erstmal alles interpretiert haben mit automatischem profiling, und dann profile-guided geJITet haben. Bzw. zumindest hat man sich das unter Javarianern damals so erzählt.
-
@hustbear,
Gut, C#, VB.Net, F#, usw. wird in CIL oder IL übersetzt und danach interpretiert. Das ist für mich aber ein eher unwichtiger Unterschied. Ob CIL oder C#, Java oder Java-Bytecode es ist einfach nur eine andere Form des Gleichen.Vielleicht müsste man auch zuerst mal definieren, was überhaupt eine interpretierte Sprache ausmacht. Ist für dich z.B. Javascript eine interpretierte Sprache? Obwohl heute viele Implementierungen einen JIT verwenden? Oder hängt dies auch mit der Ausführungsumgebung zusammen? Somit könnte auch C# (nicht CIL!) interpretiert sein, da es C# Interpreter gibt
Ich sehe meistens ein Hauptproblem bei solch einer Diskussion. Die Leute wollen "ihre" Sprache nicht als interpretiert abstempeln, weil sie damit etwas langsames verbinden.
Naja, ich will mich hier jetzt nicht ausführlicher äussern, da ich meine Argumente nur schlecht rüber bringen kann. Ich bin ***** müde und schlafe gleich auf der Tastatur ein
Grüssli
-
Dravere schrieb:
@hustbear,
Gut, C#, VB.Net, F#, usw. wird in CIL oder IL übersetzt und danach interpretiert. Das ist für mich aber ein eher unwichtiger Unterschied. Ob CIL oder C#, Java oder Java-Bytecode es ist einfach nur eine andere Form des Gleichen.Also für mich ist das ein wichtiger Unterschied.
Vielleicht müsste man auch zuerst mal definieren, was überhaupt eine interpretierte Sprache ausmacht.
Müsste man wohl.
* Eine Sprache die nur interpretiert und nie (vollständig) native übersetzt werden kann. Schliesst fast alle Sprachen aus.
* Eine Sprache die auch interpretiert werden kann. Schliesst fast alle Sprachen ein.
* Eine Sprache die üblicherweise interpretiert wird. Ist etwas schwammig. Und schliesst IMO C#, Lua etc. aus.
* Eine Sprache die üblicherweise (zumindest teilweise) zur Runtime interpretiert oder geJITed wird.Ich glaube aber dass du was ganz anderes meinst, wo IMO der Begriff "interpretiert" schon gar nicht angebracht ist. Nämlich das Vorhandensein von viel Meta-Infos, und diversen Features die sich mit compilierten Sprachen nur mit Einbindung eines Compilers machen lassen. Wie z.B. das "Ausführen von Strings".
----
Wenns dich morgen noch freut schreib vielleicht mal ganz grob was du dir als Definition vorgestellt hättest.
-
Hallo,
die Unterscheidung zwischen kompiliert und interpretiert ist eigentlich ganz einfach zu machen. Bei der Kompilation wird Maschinencode generiert wird, sprich selber lauffähig, bei der Interpretation wird die Anweisung nicht in Maschinencode umgewandelt, sondern der Interpreter führt die Anweisung aus. Es ist also eine zweite Instanz zur Durchführung der eigentlichen Aktion notwendig.
.Net Code liegt nach der Kompilation durch den "Sprachencompiler" (C#, VB.Net, C++/CLI usw.) als Byte Code (hier CIL) vor, das ist natürlich richtig. Aber dieser Bytecode wird immer! vor der Ausführung in Maschinencode kompiliert durch den JIT Compiler und erst dieser Maschinencode wird direkt ausgeführt. Deshalb ist die Verwendung des Begriffes interpretiert bei .Net völlig falsch, da da nichts interpretiert wird. Die Möglichkeit Bytecode zu interpretieren gibts bei .Net gar nicht.
Bei Java gibts dagegen beides. Bei den ersten Versionen wurde der Java Bytecode interpretiert, aber den JIT Compiler gibts da mittlerweile auch schon ewig und der wird heute defaultmäßig eingesetzt.
Dieser ganze Prozess Prozess bei .Net ist nicht ganz einfach zu sehen für den User, da der Sprachencompiler wie schon gesagt wurde, eine PE Datei (mit der Endung exe) erzeugt die CIL enthält. Der JIT Compiler erzeugt aber keine neue Datei, sondern ersetzt in genau dieser Datei den Bytecode durch entsprechenden, kompilierten Maschinencode und dieser wird dann ausgeführt. Deshalb ist der ganze Prozess auch so undurchsichtig von außen und man könnte auf die Idee kommen das die .Net Runtime direkt den Bytecode verwendet, dem ist aber nicht so. Ob eine Exe jetzt Bytecode oder schon Maschinencode enthält (vielleicht durch ngen schon vorerzeugt),sieht man der Datei ohne tiefere Betrachtung nicht an.
Aber da gibts gute Literatur zu wie z.B. "CLR via C#" von Jeffrey Richter.
Der deutsche Wikibeitrag zu Interpreter ist übrigens falsch. Dort wird geschrieben, dass der JIT Compiler den Code in Maschinencode kompiliert der direkt ausgeführt wird und im nächsten Satz wird gesagt, dass der JIT Compiler ein Interpreter ist
Der englische dagegen erklärts richtig: http://en.wikipedia.org/wiki/Interpreter_(computing).
-
@Zwergli: Guter Beitrag!
-
Kann man ja nachvollziehen.
Wenn man eine .Net Applikation das erste mal auf ein System startet ist es recht langsam, das liegt daran das der IL Code in den AssemblyCache gebaut wird und von dort dann nur noch ausgeführt. Beim nächsten start merkt die Runtime dann das sich der IL nicht geändert hat und der Build noch da ist und startet direkt ohne bau.
Dadurch sind alle nachfolgenden Starts der selben Applikation schneller.
-
Zwergli schrieb:
die Unterscheidung zwischen kompiliert und interpretiert ist eigentlich ganz einfach zu machen. Bei der Kompilation wird Maschinencode generiert wird, sprich selber lauffähig, bei der Interpretation wird die Anweisung nicht in Maschinencode umgewandelt, sondern der Interpreter führt die Anweisung aus.
http://en.wikipedia.org/wiki/Interpreter_(computing).Dem will ich widersprechen. Interpreter können mindestens in zwei Architekturformen vorkommen.
- Code liegt als Datenstruktur vor, der über eine Maschinenform(Stack oder Register) getrieben wird (Abstrakte Maschine)
- Code wird zur Laufzeit in Maschinencode transformiert.
-
Und wo ist jetzt der Widerspruch?
-
David W schrieb:
Und wo ist jetzt der Widerspruch?
Seine Aussage war, dass beim Interpreter nicht ins Maschinenform übersetzt wird.