Я заинтересован в использовании/изучении RoR в проекте, где я должен использовать .NET dll. Способен ли Ruby импортировать .NET dll?
Может ли Ruby импортировать .NET dll?
Ответы (7)
В то время как IronRuby быстро разговаривает с вашей .NET dll (это будет буквально вообще без кода), Microsoft отказалась от него, и у него никогда не было достаточно большого сообщества с открытым исходным кодом, чтобы продолжать его работу после этого события. Я бы не рекомендовал это в наши дни
Что касается COM-решения, это действительно может быть хорошим способом.
Вам не нужна библиотека RubyCOM, которая позволяет другим COM-объектам вызывать код ruby. Чтобы загрузить COM-объекты из ruby, вам просто нужна библиотека win32ole
, которая входит в состав стандартной библиотеки для windows ruby.
Сможете ли вы загрузить dll из COM, будет зависеть от того, была ли .NET dll построена так, чтобы быть «видимой для Com». Платформа .NET определяет ComVisibleAttribute
, который можно применять либо ко всей сборке, либо к определенным классам в сборке. Если для него установлено значение true либо для всей сборки, либо для каких-либо классов, то dll уже будет вызываться из COM без кода-оболочки.
Вот тест, который я сделал.
Создайте новый проект .NET dll (библиотека классов). Вот пример класса, который я использовал:
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 );
}
}
}
}
Теперь в проекте визуальной студии есть каталог с именем Properties
, который содержит AssemblyInfo.cs
. В этом файле будет следующее
[assembly: ComVisible( false )]
Меняем ложь на истину. Если вы не хотите, чтобы каждый класс в сборке был открыт для COM, вы можете оставить для него значение false в AssemblyInfo.cs
и вместо этого поместить его над каждым классом, который вы хотите предоставить, например так:
[ComVisible( true )]
public class LogWriter ....
Теперь щелкните правой кнопкой мыши сам проект dll и во всплывающем меню выберите «Свойства». В списке разделов выберите Build
Прокрутите вниз и установите флажок «Зарегистрироваться для COM-взаимодействия». Теперь, когда вы скомпилируете эту DLL, Visual Studio сделает все необходимое для загрузки информации COM в реестр. Обратите внимание, что если вы используете Vista, вам нужно запустить VS от имени администратора, чтобы это работало.
Теперь, когда это сделано, перекомпилируйте вашу dll, а затем создайте новый файл ruby.
В этом ruby-файле сделайте следующее:
require 'win32ole'
lib = WIN32OLE.new('[Solution name].ComLib.LogWriter')
lib.WriteLine('calling .net from ruby via COM, hooray!')
Где [Имя решения] должно быть заменено именем только что созданного решения (по умолчанию: "ClassLibrary1").
Руби этот рубиновый файл, и вуаля! вы должны увидеть, что текст записывается в c:\log.file
.
Одна из проблем с этим решением заключается в том, что оно требует, чтобы .NET dll уже была Com Visible, или, если это не так, у вас есть возможность перекомпилировать ее. Если ни один из этих пунктов не соответствует действительности, возможно, вам придется рассмотреть другие варианты.
Удачи!
Вы также можете написать собственную DLL-оболочку -> С#, используя управляемый С++.
Экспортируйте все функции, которые вы хотите, как вызовы C в DLL, например.
extern "C" __declspec ( dllexport ) void CallManagedMethod() {
Something^ myManagedObject ...
}
Затем используйте FFI для вызова этой DLL из Ruby https://github.com/ffi/ffi.
Если вы хотите использовать «обычный» рубин (поскольку я не думаю, что IronRuby полностью запускает RoR), вы можете использовать COM, т.е.
"Your Ruby Code" -> RubyCOM -> "COM-Callable Wrappers" -> "Your .NET objects"
Хотя это немного запутанно.
Изменить: лучший вариант на основе COM в другом месте ответов
Другое дело - может быть лучше подумать об этом больше с точки зрения сервис-ориентированной архитектуры. Можете ли вы взять эту .NET DLL и предоставить ее как службу?
За кулисами вы можете писать модули Ruby на C, поэтому вы всегда можете написать взаимодействие, чтобы делать то, что вам нужно. Однако это ограничит ваше развертывание платформами Windows (я не пробовал Ruby-> Interop-> Mono)
Вот презентация, которую я сделал пару лет назад под названием Ruby для разработчиков C#. Это немного устарело (это было до того, как проект Джона Лама был включен в IronRuby), но может немного помочь.
Если вы используете IronRuby (реализация Ruby, построенная на .Net), то это должно быть возможно. Если вы уже используете .Net и хотите попробовать Ruby, возможно, вы захотите изучить IronRuby.
За пределами IronRuby я не уверен. Я сам не использовал Ruby, поэтому не знаю, на что он способен.
Хотя, насколько я понимаю, это мертвый проект, вы можете найти предыдущий проект RubyCLR Джона Лама (который сейчас отвечающий за IronRuby) интересный.
Если вы заинтересованы в совместном использовании ASP.NET MVC с IronRuby, вы можете проверить этот исходный код от Джимми - http://github.com/jschementi/ironrubymvc/tree/masterа>
Наслаждаться!