Pergunta

Eu tenho um projeto C# no qual incorporei um programa IronRuby.O projeto (incluindo meu script Ruby) é compilado em um arquivo .exe no Visual Studio 2010 para distribuição.Estou usando um padrão semelhante a este para inicializar o script IronRuby: http://pastebin.com/NKes1cyc (e Jimmy Schementi entra em mais detalhes aqui: http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html).

Meu problema:Gostaria de incorporar uma gema (json_pure) em meu assembly C# e chamá-la a partir do script Ruby.

Alguns recursos que encontrei:

  1. No JRuby, você pode facilmente empacotar uma gem em um arquivo jar e simplesmente solicitar o arquivo jar em tempo de execução - http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar

  2. A ferramenta irpack (em http://github.com/kumaryu/irpack) é capaz de compilar Ruby em um .exe (acho que ele cria e compila dinamicamente um projeto C#) enquanto incorpora a biblioteca padrão Ruby.Mas parece que ele está incorporando apenas os arquivos .dlls IronRuby pré-construídos, não os arquivos .rb ruby.A abordagem que esta ferramenta usa funcionaria se eu pudesse descobrir como compilar arquivos de origem Ruby em um .dll.

Como incorporo uma gema IronRuby em um assembly C# (ou compilo uma gema IronRuby em um .dll)?

EDITAR:

Página 472 de IronRuby em ação ("Usando Bibliotecas Externas") explica como exigir bibliotecas Ruby padrão de dentro de um arquivo Ruby incorporado.Envolve adicionar as pastas à coleção de caminhos de pesquisa de tempo de execução, conforme a seguir (editado por questões de brevidade e clareza):

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)

Esta abordagem assume que a máquina host tem o IronRuby instalado, mas eu quero incorporar arquivos Ruby (de uma gem) no assembly para que ele possa ser executado sem o IronRuby pré-instalado.

EDIÇÃO 2 (pesquisas adicionais):

Lendo o código-fonte da ferramenta irpack mencionada acima, percebo que Kumaryu está incorporando recursos na montagem final por meio da classe System.IO.Packaging.Package e, em seguida, passando o pacote para a chamada para msbuild (consulte https://github.com/kumaryu/irpack/blob/master/lib/irpack/packager.rb).Talvez algumas pesquisas adicionais sobre empacotamento de arquivos em um executável levassem a uma solução.O problema que vejo é que os arquivos Ruby em uma jóia require outros arquivos Ruby ...pode um arquivo Ruby em um pacote assembly require outros arquivos Ruby no mesmo pacote?

EDITAR 3:

Ainda não obtive resposta, mas estaria interessado em ouvir o feedback de alguém, mesmo que seja apenas um link ou uma sugestão sobre onde procurar.Sou novo no msbuild e a documentação é bastante robusta.Uma pesquisa inicial na web por “pacote zip incorporado msbuild” não revelou nada relevante.

Foi útil?

Solução

Exigir é um método que pode ser substituído como qualquer outro método Ruby.Eu acho que é assim que o pacote Ruby Gems original funcionava, as gemas simplesmente substituiriam require.

Se você puder empacotar a gema em seu .exe de alguma forma, poderá substituir require para carregar da montagem.

Outras dicas

estou trabalhando com https://stackoverflow.com/users/2086/mcintyre321 para envolver sua biblioteca em C#/IronRuby usando meu código de empacotamento ( https://github.com/rifraf/IronRubyAppPackager#readme ).

Existem algumas correções necessárias na etapa de vendorização relacionadas às versões posteriores do Ruby com RubyGems incorporados em vez de carregados, mas o progresso está sendo feito.

Seu código requer 'json', e eu tenho um truque para forçá-lo a usar a implementação Ruby em vez dos arquivos .so do C-linkage.Isso deve significar que funcionará bem com o IronRuby.Farei um relatório ou sinta-se à vontade para entrar em contato comigo com a fonte que você deseja publicar.

tente isso https://github.com/rifraf/IronRubyAppPackager#readme (ou espere que eu informe se funciona com a biblioteca que estou tentando incorporar)

Reportando de volta:

O processo que eu passei é...

  1. fork e submódulo todos os projetos (IronRubyEmbeddedApps, IronRubyAppPackager, Serfs e Vendorize) de https://github.com/rifraf, e adicionei todos eles em uma solução VS.Atualizei todos os projetos para .NET4 e fiz com que eles se referissem uns aos outros, em vez dos assemblies .net2 incluídos

  2. executou Vendorize para extrair todas as dependências/gemas D:\projects\SomeLibrary\lib_vendor_ Correndo:

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

  3. Gerou um projeto c# em D:\projects\SomeLibrary\lib\_IRPackager_\some_lib.csproj Correndo:

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

  4. Adicionei some_lib.csproj à minha solução, atualizei-o para .net4 e corrigi as referências

  5. Neste ponto, você pode executar o projeto em .NET, de forma independente, executando
var Ruby = new EmbeddedRuby();
Ruby.Decoder = new Program.GZipDecoder();
Ruby.Mount("App");
Ruby.Run("gocardless.rb");

E deu certo!Brilhante, pensei!

Na verdade, neste ponto, descobri que havia falhado na etapa 2 ao comercializar todas as bibliotecas necessárias.Vendorize funciona interceptando require chamadas e salvando os arquivos rb chamados no _Vendor_ - se require não for executado (então execute todos os testes e espere que a cobertura do teste seja 100%), ele não será detectado.

Por algum motivo, ele não estava selecionando um dos arquivos necessários, embora houvesse uma exigência.No final, criei manualmente o conteúdo para o fornecedor diretório copiando minha biblioteca e usando bundle install --deployment comando.Repita os passos 3 e 4 e pronto...certo?

Não, recebo algum erro sobre no such file to load -- json/pure quando executo o projeto gerado - acho que isso é algo que faz uma combinação de ironruby não ter uma implementação json nativa, eu fazendo a venda manual e tendo que consertar as coisas em vários pontos hoje.

Para concluir - este método quase funciona, funcionará se sua biblioteca e suas dependências funcionarem corretamente com o ironruby, e você poderá fazer com que o vendorize funcione corretamente.

Estou desistindo e portando a biblioteca para c# à moda antiga.

editar:conforme mencionado abaixo, rifraf está me ajudando e procurando atualizar as ferramentas que eu estava usando.Assista esse espaço!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top