本文介绍了是否有可能从R内调用COM对象,如果COM对象从.NET程序集暴露?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有可能调用从研发.NET函数,通过COM调用。

I'm wondering if it is possible to call .NET functions from R, via a COM call.

RCOM 允许调用COM对象,所以这应该是可能的,在理论上,对于公开为COM对象中的任何.NET程序集。

The library rcom allows calls to COM objects, so this should be possible, in theory, for any .NET assembly that is exposed as a COM object.

要保持它的简单,我会看看我能不能叫 .Reverse()函数 System.Text ,它在默认情况下为从.NET框架COM对象公开。

To keep it simple, I'll see if I can call the .Reverse() function in System.Text, which is exposed by default as a COM object from the .NET framework.

这是我试过到目前为止:

This is what I have tried so far:

  1. 我在我的系统(见链接到C#code )获得的程序id的列表。这是在我的系统相关的ProgID的列表:

  1. I obtained a list of ProgID's in my system (see link to C# code). Here is a list of the relevant ProgIDs in my system:

---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 code加载一个.NET .dll文件公开为COM对象:

  • This R code loads a .NET .dll exposed as a COM object:

    library('rcom')
    x <- comCreateObject("System.Text.ASCIIEncoding")
    

  • 它肯定找到COM对象:

  • Its definitely finding the COM object:

    X    ATTR(类)   1 COMObject

    我的问题是 - 我怎么叫 .Reverse()此COM对象中的功能?

  • My question is - how do I call the .Reverse() function within this COM object?

    更新

    在.NET中,电话是:

    In .NET, the call would be:

        string x = "hello".Reverse();
    

    所以,在研发,呼叫会是什么?

    So, in R, the call would be?

    更新

    有关的R调用C#示例,请参阅研究调用C中的的幻灯片61。

    For an example of R calling C#, see R calls C# in Embedding R in Applications on Windows on slide 61.

    注意的ProgId ProjectName.ClassName 从.NET类。

    推荐答案

    我刚刚成功地称之为从研发通过COM .NET code的基础上,从幻灯片61说明65的应用程序。

    I have just successfully called .NET code from R via COM, based on instructions from slide 61 to 65 of Embedding R in Applications on Windows.

    下面是R code:

    # 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
    

    下面是C#code为.NET类:

    Here is the C# code for the .NET class:

    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");
                }
            }
        }
    }
    

    备注

    1. 为了这个工作,一切都必须是一致的32位,或持续64位。我得到它的工作在32位模式下,使用以下设置:

    1. In order for this to work, everything must be consistently 32-bit, or consistently 64-bit. I got it working in 32-bit mode, by using the following settings:

    • 在C#的组件(设置为32位)。
    • R的版本(我用的转速R在32位模式下)。

    如果您使用Visual Studio 2012(VS2012),然后如果你勾选注册为COM互操作,在.NET项目的设置,它会自动运行 C:\ WINDOWS \ Microsoft.NET \框架\ v4.0.30319 \ regtlibv12.exe 来注册自定义的.NET类作为一个系统范围的COM组件,在编译。但是,如果您使用Visual Studio 2010(VS2010),将不可以自动运行 regtlibv12.exe ,这一切的设置将要做的是创建。 TLB文件(你将不得不执行 regtlibv12.exe 手动,你自己)。

    If you use Visual Studio 2012 (VS2012), then if you tick "Register for COM interop" in .NET project settings, it will automatically run C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe to register your custom .NET class as a system wide COM component, on compile. However, if you use Visual Studio 2010 (VS2010), it will not automatically run regtlibv12.exe, all this setting will do is create the .tlb file (you will have to run regtlibv12.exe manually, yourself).

    可以通过调用regtlibv12.exe -u MyComDLL.tlb取消注册COM组件。

    Can unregister a COM component by calling "regtlibv12.exe -u MyComDLL.tlb".

    如果你建立你的项目,VS2012抱怨说,它无法写入输出.dll文件,这意味着R被锁定它由于呼叫 X&LT; - comCreateObject(InteropSample。 MyClass32)。要解锁.dll文件,因此它可以被编译VS2012,接近R,编译C#,然后重新启动R上。

    If you build your project, and VS2012 complains that it cannot write the output .dll, this means that R is locking it due to the call x <- comCreateObject("InteropSample.MyClass32"). To unlock the .dll so it can be compiled VS2012, close R, compile C#, then restart R.

    其他信息

    1. 查看ř帮助 RCOM
    2. 查看用户手册 RCOM
    3. 查看 statconn维基页面
    4. 如果它不带有R v2.15工作,尝试为R v2.14。
    1. See R help on rcom package.
    2. See User manual for rcom.
    3. See the statconn Wiki page.
    4. If it doesn't work with R v2.15, try it with R v2.14.

    这篇关于是否有可能从R内调用COM对象,如果COM对象从.NET程序集暴露?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 09-05 00:08