2008-11-05 10 views

Respuesta

31

Mientras IronRuby le quitará el trabajo de hablar con su .NET dll (literalmente no habrá ningún código), fue abandonado por Microsoft, y nunca tuvo una comunidad de código abierto lo suficientemente grande como para seguir funcionando después ese evento. No lo recomendaría estos días

En cuanto a la solución COM, esta puede ser una buena forma de hacerlo.

No necesita la biblioteca RubyCOM, que permite que otros objetos COM invoquen el código Ruby. Para cargar objetos COM desde ruby, solo necesita la biblioteca win32ole, que viene como parte de la biblioteca estándar en Windows ruby.

Sea o no se puede cargar el archivo DLL de COM dependerá si el DLL .NET fue construido para ser 'Com visible'. .NET framework define un ComVisibleAttribute, que se puede aplicar a un conjunto completo o a clases específicas dentro de un ensamblaje. Si se establece en verdadero para todo el conjunto, o cualquier clase, entonces el dll ya será invocable desde COM sin ningún código de contenedor.

Aquí hay una prueba que hice.

Cree un nuevo proyecto .NET dll (biblioteca de clases). He aquí un ejemplo de clase utilicé:

using System; 
using System.IO; 

namespace ComLib 
{ 
    public class LogWriter 
    { 
     public void WriteLine(string line) 
     { 
      using(var log = new StreamWriter(File.OpenWrite(@"c:\log.file"))) 
      { 
       log.WriteLine(line); 
      } 
     } 
    } 
} 

Ahora, bajo el proyecto de Visual Studio, hay un directorio llamado Properties que contiene AssemblyInfo.cs.En este archivo, habrá el siguiente

[assembly: ComVisible(false)] 

Cambie el falso a verdadero. Si no desea que todas las clases en la asamblea se expone a COM, a continuación, puede dejarlo en falso en AssemblyInfo.cs y en lugar de ponerlo encima de cada clase que desea exponer, así:

[ComVisible(true)] 
public class LogWriter .... 

Ahora haga clic derecho en el proyecto dll en sí, y desde el menú emergente, seleccione 'propiedades'. En la lista de secciones, elija Build

Desplácese hacia abajo y marque la casilla 'Registrar para la interoperabilidad COM'. Ahora cuando compile esta DLL, Visual Studio hará las cosas necesarias para cargar la información COM en el registro. Tenga en cuenta que si está en vista necesita ejecutar VS como administrador para que esto funcione.

Ahora que lo ha hecho, recompile su dll, y luego cree un nuevo archivo ruby.

En este archivo rubí, hacer esto:

require 'win32ole' 

lib = WIN32OLE.new('[Solution name].ComLib.LogWriter') 
lib.WriteLine('calling .net from ruby via COM, hooray!') 

Donde [nombre Solución] va a ser reemplazado por el nombre de la solución que acaba de crear (por defecto: "ClassLibrary1")

Ruby que ruby file, y presto! debería ver que el texto se escribe en c:\log.file.

Un problema con esta solución es que requiere que .NET dll ya sea Com Visible, o si no lo está, tiene la capacidad de volver a compilarlo. Si ninguna de estas cosas es verdadera, entonces puede que tenga que mirar otras opciones.

¡Buena suerte!

+0

Gracias! Comprobaré la propiedad comVisible de dll para ver si puedo implementar esta solución. –

+0

Usando el código anterior, estoy accediendo al código .Net dll y me está yendo muy bien, pero quiero saber cómo cerrar esta tarea ... si quiero usar esto con frecuencia ... si uso el mismo código, frecuentemente no lo ejecutaré de nuevo ... ¿Hay alguna forma de cerrar/matar objeto? – Jeyavel

+0

¿Qué quieres decir con matar el objeto? El tiempo de ejecución de .NET administra la vida de los objetos COM por usted. Cuando el recolector de basura se ejecuta, comprobará y verá si algún código .NET está haciendo referencia al objeto COM, y si no lo hace, lo limpiará. Si .El código de red * es * todavía haciendo referencia a él, luego, para limpiarlo se produciría un error. –

0

Si usa IronRuby (implementación de Ruby basada en .Net), entonces debería ser capaz de hacerlo. Si ya está utilizando .Net y quiere probar Ruby, entonces es posible que desee buscar en IronRuby.

Fuera de IronRuby No estoy seguro. No he usado a Ruby, así que no sé de qué tipo es capaz.

2

Si desea utilizar el rubí 'normal' (ya que no creo que IronRuby corre totalmente RoR aún) que podría ser capaz de ir a través de COM - es decir,

"Your Ruby Code" -> RubyCOM -> "COM-Callable Wrappers" -> "Your .NET objects" 

RubyCom

que es un poco complicado aunque.

Editar: mejor opción basada en la OCM de las respuestas

1

Otra cosa a otra parte - que podría ser mejor que pensar en ello más de un punto de arquitectura orientada a servicios. ¿Puedes tomar esa DLL .NET y exponerla como un servicio?

Detrás de las escenas, se puede escribir módulos de Ruby en C, por lo que siempre se puede escribir una interoperabilidad para hacer lo que necesita. Sin embargo, limitará su implementación a las plataformas de Windows (no he intentado con Ruby-> Interop-> Mono)

Aquí hay una presentación que di hace un par de años llamada Ruby for C# Developers. Está un poco anticuado (fue antes de que el proyecto de John Lam se doblara en IronRuby), pero podría ayudar un poco.

+0

Exponer la DLL .NET como un servicio SOA es un camino a seguir, pero voy a tener que comprobar los problemas de seguridad de hacer esto. –

0

Aunque es un proyecto muerto AFAIK, es posible que el anterior RubyCLR project de John Lam (que ahora está a cargo de IronRuby) sea interesante.

3

También puede escribir un nativo -> C# envoltorio utilizando DLL de C++

exportar todas las funciones que desea como C llama en la DLL, por ejemplo,

extern "C" __declspec (dllexport) void CallManagedMethod() { 
    Something^ myManagedObject ... 
} 

A continuación, utilice FFI para llamar a esa DLL desde Ruby https://github.com/ffi/ffi