I'm wondering if it is possible to call .NET functions from R, via a COM call.
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.
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:
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---
This R code loads a .NET .dll exposed as a COM object:
library('rcom') x <- comCreateObject("System.Text.ASCIIEncoding")
Its definitely finding the COM object:
x attr(,"class") 1 "COMObject"
My question is - how do I call the
.Reverse()
function within this COM object?
Update
In .NET, the call would be:
string x = "hello".Reverse();
So, in R, the call would be?
Update
For an example of R calling C#, see R calls C# in Embedding R in Applications on Windows on slide 61.
Note that ProgId
is ProjectName.ClassName
from .NET class.
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.
Here is the R code:
Here is the output within R:
Here is the C# code for the .NET class:
Notes
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:
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 runregtlibv12.exe
, all this setting will do is create the .tlb file (you will have to runregtlibv12.exe
manually, yourself).Can unregister a COM component by calling "regtlibv12.exe -u MyComDLL.tlb".
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.Additional Information
rcom
package.rcom
.I know this question is old, I'm reporting my experience to help out future .Net/R developers.
No matter what I tried I could not Reference
rcom_srv.tlb
A reference to
C:\Program Files\R\R-2.15.3\library\rcom\libs\i386\rcom_srv.tlb
could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.I found this article where they use both RCOMServerLib and STATCONNECTORSRVLib:
I wasn't able to make progress with either, so I eventually I did it without the RcomServerLib:
And I call this via R:
COM doesn't support generics, so I simply returned a string array. I found R only supports basic/primitive .Net types, eg string, datetime, int & etc. When I tried to return a object array, it failed and the .Net call returned NULL to R.
Well in general you use
comInvoke
:However, since neither
System.Text.ASCIIEncoding
norstring
have aReverse
method, you need to pick a different method to execute.