windows Ruby 可以导入 .NET dll 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/265879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:33:38  来源:igfitidea点击:

Can Ruby import a .NET dll?

.netwindowsrubycomdll

提问by Rafael Arie

I am interested in using/learning RoR in a project where I have to use a .NET dll. Is Ruby capable of importing a .NET dll?

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

回答by Orion Edwards

While IronRuby will make short work of talking to your .NET dll (it'll be literally no code at all), it was abandoned by microsoft, and it never got a large enough open source community to keep it going after that event. I wouldn't recommend it these days

虽然 IronRuby 可以很短地与您的 .NET dll 对话(它实际上根本没有代码),但它已被微软放弃,并且它从未有一个足够大的开源社区来在该事件之后继续运行。这些天我不推荐它

Regarding the COM solution, this may actually be a good way to go.

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

You don't need the RubyCOM library - that lets other COM objects call into ruby code. To load COM objects from ruby, you just need the win32olelibrary, which comes as part of the standard library on windows ruby.

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

Whether or not you can load the dll from COM will depend if the .NET dll was built to be 'Com Visible'. The .NET framework defines a ComVisibleAttribute, which can be applied to either an entire assembly, or specific classes within an assembly. If it is set to true for either the whole assembly, or any classes, then the dll will already be callable from COM without any wrapper code.

您是否可以从 COM 加载 dll 将取决于 .NET dll 是否构建为“Com Visible”。.NET 框架定义了一个ComVisibleAttribute,它可以应用于整个程序集或程序集中的特定类。如果它为整个程序集或任何类设置为 true,则 dll 将已经可以从 COM 调用而无需任何包装代码。

Here's a test I did.

这是我做的一个测试。

Create a new .NET dll project (class library). Here's an example class I used:

创建一个新的 .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 );
            }
        }
    }
}

Now, under the visual studio project, there is a directory called Propertieswhich contains AssemblyInfo.cs. In this file, there will be the following

现在,在 Visual Studio 项目下,有一个名为的目录Properties,其中包含AssemblyInfo.cs. 在这个文件中,会有以下内容

[assembly: ComVisible( false )]

Change the false to true. If you don't want every classin the assembly exposed to COM, then you can leave it set to false in AssemblyInfo.csand instead put it above each class you want to expose, like this:

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

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

Now right click on the dll project itself, and from the popup menu, select 'properties'. In the list of sections, choose Build

现在右键单击 dll 项目本身,然后从弹出菜单中选择“属性”。在部分列表中,选择Build

Scroll down, and tick the 'Register for COM interop' checkbox. Now when you compile this DLL, visual studio will do the neccessary stuff to load the COM information into the registry. Note if you're on vista you need to run VS as an administrator for this to work.

向下滚动,并勾选“注册 COM 互操作”复选框。现在,当您编译此 DLL 时,visual studio 将执行必要的操作以将 COM 信息加载到注册表中。请注意,如果您使用的是 vista,则需要以管理员身份运行 VS 才能正常工作。

Now that this is done, recompile your dll, and then create a new ruby file.

现在完成了,重新编译你的 dll,然后创建一个新的 ruby​​ 文件。

In this ruby file, do this:

在这个 ruby​​ 文件中,执行以下操作:

require 'win32ole'

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

Where [Solution name] is to be replaced by the name of the solution you just created (default: "ClassLibrary1")

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

Ruby that ruby file, and presto! you should see that the text gets written to c:\log.file.

Ruby 那个 ruby​​ 文件,并且很快!您应该看到文本被写入c:\log.file.

One problem with this solution is that it requires that the .NET dll is already Com Visible, or if it's not, you have the ability to recompile it. If neither of these things are true, then you may have to look at other options.

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

Good luck!

祝你好运!

回答by Rich

You can also write a native -> C# wrapper DLL using managed C++

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

Export all the functions you want as C calls in the DLL, e.g.

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

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

Then use FFI to call that DLL from Ruby https://github.com/ffi/ffi

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

回答by mackenir

If you want to use 'normal' ruby (since I dont think IronRuby fully runs RoR yet) you might be able to go via COM - ie

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

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

RubyCom

红宝石

That's a bit convoluted though.

不过这有点绕。

Edit: better COM-based option elsewhere in the answers

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

回答by Cory Foy

Another thing - it might be better to think about it more from a Service-Oriented Architecture point. Can you take that .NET DLL and expose it as a service?

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

Behind the scenes, you can write Ruby modules in C, so you can always write an interop to do what you need. It will limit your deployment to Windows platforms, though (I haven't tried Ruby->Interop->Mono)

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

Here's a presentation I gave a couple of years back called Ruby for C# Developers. It's a little dated (It was before John Lam's project got folded into IronRuby), but might help a little.

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

回答by Herms

If you use IronRuby (Ruby implementation built on .Net) then it should be able to. If you're already using .Net and want to try out Ruby then you might want to look into IronRuby.

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

Outside of IronRuby I'm not sure. I haven't used Ruby myself, so I don't know what kinds of things it's capable of.

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

回答by Thibaut Barrère

Although it's a dead project AFAIK, you may find the previous RubyCLR projectby John Lam (who is now in charge of IronRuby) an interesting one.

尽管 AFAIK 这是一个已死的项目,但您可能会发现John Lam(现在负责 IronRuby)之前的RubyCLR 项目很有趣。

回答by Jirapong

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

如果您对 ASP.NET MVC 和 IronRuby 感兴趣,您可能会发现自己查看了 Jimmy 的源代码 - http://github.com/jschementi/ironrubymvc/tree/master

Enjoy!

享受!