Может ли Ruby импортировать .NET dll?

Я заинтересован в использовании / изучении RoR в проекте, где мне нужно использовать .NET dll. Может ли Ruby импортировать DLL .NET?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
15
0
11 516
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Если вы используете IronRuby (реализация Ruby, построенная на .Net), она должна быть в состоянии. Если вы уже используете .Net и хотите попробовать Ruby, возможно, вам стоит заглянуть в IronRuby.

За пределами IronRuby я не уверен. Я сам не использовал Ruby, поэтому не знаю, на что он способен.

Если вы хотите использовать «нормальный» рубин (поскольку я не думаю, что IronRuby еще полностью запускает RoR), вы можете использовать COM - т.е.

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

RubyCom

Хотя это немного запутано.

Обновлено: лучший вариант на основе COM в другом месте в ответах

Другое дело - было бы лучше подумать об этом с точки зрения сервис-ориентированной архитектуры. Можете ли вы взять эту .NET DLL и предоставить ее как услугу?

За кулисами вы можете писать модули Ruby на C, поэтому вы всегда можете написать взаимодействие, чтобы делать то, что вам нужно. Однако это ограничит ваше развертывание платформами Windows (я не пробовал Ruby-> Interop-> Mono)

Вот презентация, которую я провел пару лет назад, под названием Ruby для разработчиков на C#. Это немного устарело (это было до того, как проект Джона Лэма превратился в IronRuby), но может немного помочь.

Разоблачить .NET dll как службу SOA - это неплохой вариант, но мне придется проверить связанные с этим проблемы безопасности.

Rafael Arie 06.11.2008 16:00
Ответ принят как подходящий

В то время как IronRuby быстро справится с разговором с вашей .NET dll (в буквальном смысле слова вообще не будет кода), Microsoft отказалась от него, и у него никогда не было достаточно большого сообщества с открытым исходным кодом, чтобы поддерживать его после этого события. Я бы не рекомендовал это в наши дни

Что касается решения COM, это может быть действительно хорошим вариантом.

Вам не нужна библиотека RubyCOM, которая позволяет другим COM-объектам вызывать код Ruby. Чтобы загрузить COM-объекты из Ruby, вам просто понадобится библиотека win32ole, которая входит в стандартную библиотеку Windows Ruby.

Сможете ли вы загрузить DLL из COM или нет, будет зависеть от того, была ли построена DLL .NET как «Com Visible». Платформа .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 );
            }
        }
    }
}

Теперь в проекте Visual Studio есть каталог Properties, содержащий AssemblyInfo.cs. В этом файле будут следующие

[assembly: ComVisible( false )]

Измените false на true. Если вы не хотите, чтобы каждый класс в сборке, доступной для COM, вы можете оставить для него значение false в AssemblyInfo.cs и вместо этого поместить его над каждым классом, который вы хотите предоставить, например:

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

Теперь щелкните правой кнопкой мыши сам проект dll и во всплывающем меню выберите «Свойства». В списке разделов выберите Build

Прокрутите вниз и установите флажок «Зарегистрироваться для COM-взаимодействия». Теперь, когда вы скомпилируете эту DLL, Visual Studio сделает все необходимое для загрузки информации COM в реестр. Обратите внимание, что если вы находитесь в перспективе, вам нужно запустить VS от имени администратора, чтобы это работало.

Теперь, когда это сделано, перекомпилируйте вашу dll, а затем создайте новый файл 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, или, если это не так, у вас есть возможность перекомпилировать его. Если ни одно из этих утверждений не соответствует действительности, возможно, вам придется рассмотреть другие варианты.

Удачи!

Спасибо! Я проверю свойство comVisible библиотеки dll, чтобы узнать, смогу ли я реализовать это решение.

Rafael Arie 06.11.2008 16:01

Используя приведенный выше код, я получаю доступ к коду .Net dll и отлично справляюсь, но я хочу знать, как закрыть эту задачу ... если я хочу использовать это часто .... если я использую тот же код, я часто имею в виду, что не буду запускать его снова ... Есть ли способ закрыть / убить объект?

Jeyavel 23.12.2010 13:53

Что вы имеете в виду, говоря «убить объект»? Среда выполнения .NET управляет временем существования COM-объектов за вас. Когда сборщик мусора запускается, он проверяет, ссылается ли какой-либо код .NET на COM-объект, а если нет, он его очищает. Если код .NET является все еще ссылается на него, то его очистка вызовет ошибку.

Orion Edwards 29.12.2010 00:46

Я знаю, что это старый вопрос, но, установив флажок «Зарегистрировать для COM-взаимодействия», он будет работать только в том ящике, на котором он был скомпилирован, или мне придется зарегистрировать его в ящике, который я собираюсь его использовать.

Rig 28.02.2015 23:01

@OrionEdwards Я знаю, что это старый вопрос, но это действительно могло спасти мне день. После регистрации я создал новый файл ruby, сохранил его на своем рабочем столе и удалил его. Я получил эту ошибку: `initialize ': unknown OLE server: Есть идеи, что я делаю не так?

Itzik984 14.12.2016 15:49

Как правильно зарегистрировать эту dll?

Aleksey 30.12.2016 10:25

Хотя это мертвый проект AFAIK, вы можете найти предыдущий Проект RubyCLR Джона Лэма (который сейчас отвечает за IronRuby) интересным.

If you are interested in ASP.NET MVC with IronRuby together, You may find yourself to check out this source code from Jimmy - http://github.com/jschementi/ironrubymvc/tree/master

Наслаждаться!

Вы также можете написать собственную -> DLL-оболочку C#, используя управляемый C++

Экспортируйте все функции, которые вы хотите, как вызовы C в DLL, например

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

Затем используйте FFI для вызова этой DLL из Ruby https://github.com/ffi/ffi

Другие вопросы по теме