Wie kann ich einen Ruby-Gem in ein C#-Projekt einbetten und ihn von einem eingebetteten IronRuby-Skript anfordern?

StackOverflow https://stackoverflow.com/questions/9333732

Frage

Ich habe ein C#-Projekt, in das ich ein IronRuby-Programm eingebettet habe.Das Projekt (einschließlich meines Ruby-Skripts) wird zur Verteilung in Visual Studio 2010 in eine .exe-Datei kompiliert.Ich verwende ein ähnliches Muster zum Bootstrapping des IronRuby-Skripts: http://pastebin.com/NKes1cyc (und Jimmy Schementi geht hier näher darauf ein: http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html).

Mein Problem:Ich möchte ein Juwel (json_pure) in meine C#-Assembly einbetten und es über das Ruby-Skript aufrufen.

Einige Ressourcen, die ich gefunden habe:

  1. In JRuby können Sie ein Gem ganz einfach in eine JAR-Datei packen und die JAR-Datei dann einfach zur Laufzeit benötigen – http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar

  2. Das irpack-Tool (at http://github.com/kumaryu/irpack) ist in der Lage, Ruby in eine EXE-Datei zu kompilieren (ich glaube, es erstellt und kompiliert dynamisch ein C#-Projekt), während die Ruby-Standardbibliothek eingebettet wird.Aber es sieht so aus, als ob nur die vorgefertigten IronRuby-DLLs eingebettet werden, keine Ruby-.rb-Dateien.Der von diesem Tool verwendete Ansatz würde funktionieren, wenn ich herausfinden könnte, wie man Ruby-Quelldateien in eine DLL kompiliert.

Wie bette ich ein IronRuby-Gem in eine C#-Assembly ein (oder kompiliere ein IronRuby-Gem in eine DLL)?

BEARBEITEN:

Seite 472 von IronRuby in Aktion („Verwenden externer Bibliotheken“) erklärt, wie Sie Standard-Ruby-Bibliotheken aus einer eingebetteten Ruby-Datei heraus benötigen.Dazu gehört das Hinzufügen der Ordner zur Sammlung der Laufzeitsuchpfade wie folgt (aus Gründen der Kürze und Klarheit bearbeitet):

ScriptEngine engine = IronRuby.Ruby.CreateEngine();
var searchPaths = engine.GetSearchPaths().Concat(new[] 
{
    "C:\\Program Files (x86)\\IronRuby 1.1\\Lib\\ruby\\1.9.1",
    "C:\\Program Files (x86)\\IronRuby 1.1\\Lib\\ironruby"
});
engine.SetSearchPaths(searchPaths)

Bei diesem Ansatz wird davon ausgegangen, dass auf dem Hostcomputer IronRuby installiert ist, ich jedoch Ruby-Dateien (von einem Gem) in die Assembly einbetten möchte, damit sie ohne vorinstalliertes IronRuby ausgeführt werden kann.

EDIT 2 (weitere Recherche):

Beim Durchlesen des Quellcodes des oben genannten irpack-Tools fällt mir auf, dass Kumaryu über die Klasse System.IO.Packaging.Package Ressourcen in die endgültige Assembly einbettet und das Paket dann an den Aufruf von msbuild übergibt (siehe https://github.com/kumaryu/irpack/blob/master/lib/irpack/packager.rb).Vielleicht würden weitere Untersuchungen zum Packen von Dateien in eine ausführbare Datei zu einer Lösung führen.Das Problem, das ich sehe, ist, dass Ruby in einem Edelstein abgelegt wird require andere Ruby-Dateien...kann eine Ruby-Datei in einem Assembly-Paket enthalten require andere Ruby-Dateien im selben Paket?

EDIT 3:

Ich bin noch nicht weiter zu einer Antwort gekommen, würde mich aber über Rückmeldungen von jemandem freuen, auch wenn es sich nur um einen Link oder einen Vorschlag handelt, wo ich suchen sollte.Ich bin neu bei msbuild und die Dokumentation ist ziemlich umfangreich.Eine erste Websuche nach „msbuild embed zip package“ ergab nichts Relevantes.

War es hilfreich?

Lösung

Require ist eine Methode Das kann wie jede andere Ruby-Methode überschrieben werden.Ich denke, dass das ursprüngliche Ruby-Gems-Paket so funktionierte, Edelsteine ​​würden es einfach überschreiben require.

Wenn Sie den Edelstein irgendwie in Ihre EXE-Datei packen können, können Sie ihn überschreiben require aus der Baugruppe laden.

Andere Tipps

Ich arbeite mit https://stackoverflow.com/users/2086/mcintyre321 um seine Bibliothek mithilfe meines Verpackungscodes in C#/IronRuby zu packen ( https://github.com/rifraf/IronRubyAppPackager#readme ).

Im Vendorize-Schritt sind einige Korrekturen erforderlich, die sich darauf beziehen, dass in späteren Ruby-Versionen RubyGems eingebettet statt geladen ist, aber es werden Fortschritte erzielt.

Sein Code erfordert „json“, und ich habe einen Trick, um ihn dazu zu zwingen, die Ruby-Implementierung anstelle der C-Linkage-.so-Dateien zu verwenden.Dies sollte bedeuten, dass es mit IronRuby ok funktioniert.Ich werde Ihnen Bericht erstatten oder Sie können mich gerne mit der Quelle kontaktieren, die Sie ausführen möchten.

Versuche dies https://github.com/rifraf/IronRubyAppPackager#readme (Oder warten Sie, bis ich Ihnen berichte, ob es mit der Bibliothek funktioniert, die ich einbetten möchte.)

Rückmeldung:

Der Prozess, den ich durchlaufen habe, ist...

  1. Fork und Submodul aller Projekte (IronRubyEmbeddedApps, IronRubyAppPackager, Serfs und Vendorize) von https://github.com/rifraf, und fügte sie alle einer VS-Lösung hinzu.Ich habe alle Projekte auf .NET4 aktualisiert und dafür gesorgt, dass sie aufeinander verweisen und nicht auf die enthaltenen .net2-Assemblys

  2. Vendorize wurde ausgeführt, um alle Abhängigkeiten/Gems zu entfernen D:\projects\SomeLibrary\lib_vendor_ durch Ausführen:

    D:\projects\SomeLibrary\lib>ruby -I..\..\Vendorize\lib -rvendorize some_lib.rb

  3. Erstellt ein C#-Projekt unter D:\projects\SomeLibrary\lib\_IRPackager_\some_lib.csproj durch Ausführen:

    D:\projects\SomeLibrary\lib>ruby -I..\..\IronRubyAppPackager\lib\IRPackager.rb some_lib.rb

  4. Some_lib.csproj wurde zu meiner Lösung hinzugefügt, auf .net4 aktualisiert und Referenzen korrigiert

  5. An diesem Punkt können Sie das Projekt in .NET eigenständig ausführen, indem Sie ausführen
var Ruby = new EmbeddedRuby();
Ruby.Decoder = new Program.GZipDecoder();
Ruby.Mount("App");
Ruby.Run("gocardless.rb");

Und es ist gelungen!Genial, dachte ich!

Tatsächlich stellte ich zu diesem Zeitpunkt fest, dass es in Schritt 2 nicht gelungen war, jede einzelne erforderliche Bibliothek anzubieten.Verkaufen Sie Werke durch Abfangen require Aufrufe und anschließendes Speichern der aufgerufenen RB-Dateien im _Vendor_ - Wenn require nicht ausgeführt wird (also alle Tests ausführen und hoffen, dass die Testabdeckung 100 % beträgt), wird er nicht übernommen.

Aus irgendeinem Grund wurde eine der erforderlichen Dateien nicht abgerufen, obwohl eine Anforderung bestand.Am Ende habe ich den Inhalt manuell erstellt Verkäufer Verzeichnis durch Kopieren meiner Bibliothek und durch Verwenden bundle install --deployment Befehl.Wiederholen Sie Schritt 3 und 4 und ich bin fertig ...Rechts?

Nein, ich bekomme eine Fehlermeldung no such file to load -- json/pure Wenn ich das generierte Projekt ausführe, denke ich, dass dies eine Kombination aus IronRuby ohne native JSON-Implementierung, der manuellen Vendorisierung und der Tatsache ist, dass ich heute an mehreren Stellen etwas ändern muss.

Zusammenfassend lässt sich sagen, dass diese Methode fast funktioniert, wenn Ihre Bibliothek und ihre Abhängigkeiten ordnungsgemäß mit IronRuby funktionieren und Sie Vendorize ordnungsgemäß zum Laufen bringen können.

Ich gebe auf und portiere die Bibliothek auf die altmodische Art und Weise nach C#.

bearbeiten:Wie unten erwähnt, hilft mir Rifraf und prüft die Aktualisierung der von mir verwendeten Tools.Pass auf diesen Raum auf!

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