gpt4 book ai didi

.net - 如果 COM 对象是从 .NET 程序集中公开的,是否可以从 R 中调用 COM 对象?

转载 作者:行者123 更新时间:2023-12-05 00:31:21 24 4
gpt4 key购买 nike

我想知道是否可以通过 COM 调用从 R 调用 .NET 函数。

图书馆rcom允许调用 COM 对象,因此从理论上讲,对于任何公开为 COM 对象的 .NET 程序集,这应该是可能的。

为简单起见,我会看看我是否可以调用 .Reverse() System.Text中的函数,默认情况下作为 .NET 框架中的 COM 对象公开。

这是我到目前为止所尝试的:

  • 我在我的系统中获得了 ProgID 的列表(参见 link to C# code)。这是我系统中相关 ProgID 的列表:
    ---start list of COM ProgID entries---
    <snip>
    System.SystemException -> mscoree.dll
    System.Text.ASCIIEncoding -> mscoree.dll
    System.Text.StringBuilder -> mscoree.dll
    System.Text.UnicodeEncoding -> mscoree.dll
    System.Text.UTF7Encoding -> mscoree.dll
    System.Text.UTF8Encoding -> mscoree.dll
    <snip>
    ---end list---
  • 此 R 代码加载作为 COM 对象公开的 .NET .dll:
    library('rcom')
    x <- comCreateObject("System.Text.ASCIIEncoding")
  • 它肯定会找到 COM 对象:

    x attr(,"class") 1 "COMObject"

  • 我的问题是 - 我如何调用 .Reverse() COM 对象中的函数?

  • 更新

    在 .NET 中,调用将是:
        string x = "hello".Reverse();

    那么,在 R 中,调用会是什么?

    更新

    有关 R 调用 C# 的示例,请参阅 R 调用 C# Embedding R in Applications on Windows在幻灯片 61 上。

    请注意 ProgIdProjectName.ClassName来自 .NET 类。

    最佳答案

    根据 Embedding R in Applications on Windows 第 61 至 65 页的说明,我刚刚通过 COM 从 R 中成功调用了 .NET 代码。 .

    这是R代码:

    # This is a once-off call.
    install.packages("rcom")
    library(rcom)
    # This is a once-off call. See rcom user manual at:
    # http://cran.r-project.org/web/packages/rcom/rcom.pdf
    installstatconnDCOM()

    x <- comCreateObject("InteropSample.MyClass32")
    comSetProperty(x,"Text","xxx")
    comSetProperty(x,"Connector",comThis())
    comInvoke(x,"DoCallback")

    这是R中的输出:
    > DoCallback: xxxNULL

    这是 .NET 类的 C# 代码:
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Text;

    // Before running this, get rid of errors with "RCOMServerLib" by adding the rcom type library:
    //
    // Make sure everything is 32-bit (32-bit build in .NET, 32-bit run of Revolution R).
    //
    // Tick "Register for COM interop" in .NET project settings.
    //
    // 1.Browse to "C:\Revolution\R-Enterprise-6.1\R-2.14.2\library\rcom\libs\i386>", then execute:
    // C:\Revolution\R-Enterprise-6.1\R-2.14.2\library\rcom\libs\i386> C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe rcom_srv.tlb
    // Registration of rcom_srv.tlb successful.
    //
    // 2. Add reference to "rcom_srv.tlb", this gets rid of errors for RComServerLib.
    // (browse to "C:\Revolution\R-Enterprise-6.1\R-2.14.2\library\rcom\libs\i386")
    //
    // 3. If we are using VS2012, this .NET assembly class will be automatically registered as COM server on build if we are using VS2012. If using VS2012, you must do this manually on the command line.
    //
    // See:
    // http://generally.wordpress.com/2006/07/28/exposing-your-net-assembly-through-com/
    // http://www.inside-r.org/packages/cran/rcom/docs/comCreateObject

    // In R:
    // comCreateObject("InteropSample.MyClass32")
    // comSetProperty(x,"Text","xxx")
    // comSetProperty(x,"Connector",comThis())
    // comInvoke(x,"DoCallback")

    namespace COM___called_from_R
    {
    [Guid("3ddfe021-a0c6-4218-a254-4fc4328c99a7"),
    InterfaceType(ComInterfaceType.InterfaceIsDual)]
    internal interface IMyComponent
    {
    RCOMServerLib.IStatConnector Connector { set; }
    string Text { set; }
    void DoCallback();
    }

    [Guid("133fee0e-9b32-4429-8a43-6e2a706a9beb"), ComVisible(true)]
    [ProgIdAttribute("InteropSample.MyClass32")]
    public class MyComponent : IMyComponent
    {
    private string mText;
    private RCOMServerLib.IStatConnector mConnector;

    public RCOMServerLib.IStatConnector Connector
    {
    set { mConnector = value; }
    }

    public string Text
    {
    set { mText = value; }
    }

    public string MyProperty;

    public void DoCallback()
    {
    if (mConnector != null)
    {
    mConnector.EvaluateNoReturn("cat(\"DoCallback: "
    + mText + "\")\n");
    }
    }
    }
    }

    备注
  • 为了使其正常工作,所有内容都必须始终为 32 位或始终为 64 位。通过使用以下设置,我让它在 32 位模式下工作:
  • C# 程序集(设置为 32 位)。
  • R 的版本(我在 32 位模式下使用了 Revolution R)。
  • 如果您使用 Visual Studio 2012 (VS2012),那么如果您在 .NET 项目设置中勾选“注册 COM 互操作”,它将自动运行 C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe在编译时将您的自定义 .NET 类注册为系统范围的 COM 组件。但是,如果您使用 Visual Studio 2010 (VS2010),它将 不是 自动运行regtlibv12.exe ,所有这些设置都会创建 .tlb 文件(您必须自己手动运行 regtlibv12.exe)。
  • 可以通过调用“regtlibv12.exe -u MyComDLL.tlb”取消注册 COM 组件。
  • 如果您构建您的项目,并且 VS2012 提示它无法写入输出 .dll,这意味着由于调用 x <- comCreateObject("InteropSample.MyClass32"),R 正在锁定它。 .要解锁 .dll 使其可以编译 VS2012,请关闭 R,编译 C#,然后重新启动 R。

  • 附加信息
  • R help on rcom package .
  • User manual for rcom .
  • statconn Wiki page .
  • 如果它不适用于 R v2.15,请尝试使用 R v2.14。
  • 关于.net - 如果 COM 对象是从 .NET 程序集中公开的,是否可以从 R 中调用 COM 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14862861/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com