【问题标题】:Can Ruby import a .NET dll?Ruby 可以导入 .NET dll 吗?
【发布时间】:2010-09-20 22:06:31
【问题描述】:

我有兴趣在必须使用 .NET dll 的项目中使用/学习 RoR。 Ruby 是否能够导入 .NET dll?

【问题讨论】:

    标签: .net windows ruby com dll


    【解决方案1】:

    虽然 IronRuby 可以缩短与您的 .NET dll 对话的工作(它实际上根本没有代码),但它被微软抛弃了,而且它从来没有足够大的开源社区来维持它的发展事件。这些天我不会推荐它

    关于 COM 解决方案,这实际上可能是一个不错的方法。

    您不需要 RubyCOM 库——它可以让其他 COM 对象调用 ruby​​ 代码。要从 ruby​​ 加载 COM 对象,您只需要 win32ole 库,它是 windows ruby​​ 标准库的一部分。

    是否可以从 COM 加载 dll 取决于 .NET dll 是否构建为“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 )]
    

    将假改为真。如果您不希望程序集中的每个类 都暴露给 COM,那么您可以在 AssemblyInfo.cs 中将其设置为 false,而是将它放在您想要暴露的每个类之上,如下所示:

    [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!')
    

    其中 [Solution name] 将替换为您刚刚创建的解决方案的名称(默认:“ClassLibrary1”)

    Ruby 那个 ruby​​ 文件,然后!你应该看到文本被写入c:\log.file

    此解决方案的一个问题是它要求 .NET dll 已经是 Com Visible,或者如果不是,您可以重新编译它。如果这些都不成立,那么您可能需要考虑其他选项。

    祝你好运!

    【讨论】:

    • 谢谢!我会检查 dll 的 comVisible 属性,看看我是否可以实现这个解决方案。
    • 使用上面的代码我正在访问.Net dll代码并且做得很好,但我想知道如何关闭这个任务......如果我想经常使用这个......如果我使用相同的代码我经常意味着不会再次运行它...有什么方法可以关闭 /kill 对象?
    • 杀死对象是什么意思? .NET 运行时为您管理 COM 对象的生命周期。当垃圾收集器运行时,它会检查是否有任何 .NET 代码引用了 COM 对象,如果没有,它将清理它。如果 .NET 代码正在仍然引用它,那么清理它会导致错误。
    • 我知道这是一个老问题,但是选中“注册 COM 互操作”框,是否只能在编译它的框上工作,或者我必须在框上注册它我打算用它。
    • @OrionEdwards 我知道这是一个老问题,但这确实可以节省我的时间,在完成此注册后,我创建了一个新的 ruby​​ 文件,将其保存在我的桌面上并进行了 ruby​​ 处理。我收到了这个错误:`initialize': unknown OLE server: 知道我做错了什么吗?
    【解决方案2】:

    您还可以使用托管 C++ 编写本机 -> C# 包装 DLL

    将你想要的所有函数导出为 DLL 中的 C 调用,例如

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

    然后使用 FFI 从 Ruby 调用该 DLL https://github.com/ffi/ffi

    【讨论】:

    • 嗨!我知道已经有一段时间了,但是:我已经尝试过这种方法并且一切都很顺利,直到 C++ 包装器 DLL 在运行时引用 .Net DLL 方法。然后我得到关于.Net DLL的“无法加载文件或程序集”异常。任何想法为什么? (这两个 DLL 与导出和调用 C++ 函数的 ruby​​ 脚本位于同一文件夹下。如果从同一文件夹中的 C++ 控制台应用程序调用 .Net DLL 调用,则可以正常工作。)
    • 我不知道,对不起@VitaliyProkopenko。它在 2011 年对我有用。我认为“无法加载文件或程序集”可能由于许多不同的原因而发生,您需要打开额外的诊断信息。也许提出一个新的问题,提供更多细节?总帐
    • 谢谢,@Rich。其实已经开了一个here
    【解决方案3】:

    如果您对 ASP.NET MVC 和 IronRuby 一起感兴趣,您可以查看 Jimmy 的源代码 - http://github.com/jschementi/ironrubymvc/tree/master

    享受吧!

    【讨论】:

      【解决方案4】:

      虽然 AFAIK 是一个死项目,但您可能会发现 John Lam(现在负责 IronRuby)之前的 RubyCLR project 是一个有趣的项目。

      【讨论】:

        【解决方案5】:

        如果你想使用“普通”红宝石(因为我认为 IronRuby 还没有完全运行 RoR)你可以通过 COM 去 - 即

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

        RubyCom

        这有点令人费解。

        编辑:答案中其他地方更好的基于 COM 的选项

        【讨论】:

          【解决方案6】:

          另一件事 - 从面向服务的架构角度考虑可能会更好。你能把那个 .NET DLL 作为服务公开吗?

          在幕后,您可以用 C 编写 Ruby 模块,因此您始终可以编写互操作来完成您需要的工作。不过,它会将您的部署限制在 Windows 平台上(我没有尝试过 Ruby->Interop->Mono)

          这是我几年前做的一个演示文稿,名为Ruby for C# Developers。这有点过时了(那是在 John Lam 的项目被合并到 IronRuby 之前),但可能会有所帮助。

          【讨论】:

          • 将 .NET dll 公开为 SOA 服务是一种可行的方法,但我必须检查这样做的安全问题。
          【解决方案7】:

          如果您使用 IronRuby(基于 .Net 的 Ruby 实现),那么它应该可以。如果您已经在使用 .Net 并想试用 Ruby,那么您可能需要研究 IronRuby。

          在 IronRuby 之外我不确定。我自己没用过 Ruby,所以不知道它能做什么。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-29
            • 2014-04-23
            • 2012-08-10
            • 1970-01-01
            • 2011-03-06
            • 1970-01-01
            • 2015-10-24
            • 1970-01-01
            相关资源
            最近更新 更多