是否可以调用R统计函数来优化C#函数

MBS*_*MBS 6 c# dll r

我想知道是否可以从C#调用r统计优化函数(这里我想使用regnoud),而要优化的函数是用C#编写的.我找到了RDotNet库,但有了它我无法从R评估C#函数.换句话说,问题是R在优化时需要评估函数,但他不能这样做,因为函数在C#代码中.

有没有像使用.dll或其他库的解决方案?
谢谢.

小智 10

在使用一种有点复杂的方法之前我已经这样做了但它确实有效!

首先,您需要创建一个包含您的函数的C#DLL.您可以在visual studio中通过选择"类库"作为创建新项目时的选项来执行此操作..cs文件中的代码应如下所示

namespace MyNamespace
{
    //expose an interface with functions to be called from R
    public interface MyInterface
    {
       string MyFunction(string name);
    }

    //create a class that implements the above interface
    public class MyClass : MyInterface
    {
      public string MyFunction(string name)
      {
         return "Hello " + name;
      }
    }

}
Run Code Online (Sandbox Code Playgroud)

现在编译你的项目,你将得到一个C#DLL.此DLL是托管DLL,它与本机C/C++ DLL不同.它不能直接从非.Net语言中使用,因此需要作为COM对象公开.您可以通过以下两种方式之一完成此操作

  1. 在Visual Studio中,您可以转到项目属性,单击"应用程序"选项卡下的"程序集信息"按钮,然后选中"使程序集COM可见"复选框.
  2. 或者,您可以使用可在.net安装文件夹中找到的regasm.exe将DLL注册为COM组件.这是描述此过程的链接.http://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.71).aspx.该命令通常是"regasm myTest.dll /tlb:myTest.tlb"

COM注册过程现在将在与DLL相同的文件夹中创建.tlb文件.保留此.tlb文件.我们将在下一步中使用它

下一步是创建一个可以调用COM DLL的C++ DLL.这个步骤是必需的,因为R可以直接调用C++ DLL但不能直接调用COM(如果我错了就纠正我,或者如果你知道从R调用COM的更好方法,则跳过这一步).dllmain.cpp中C++ DLL的代码如下所示(确保滚动查看完整代码)

#include "stdafx.h"
#include <iostream>

//import the .tlb file create by COM registration

#import "path_to_Dll\MyDll.tlb" named_guids raw_interfaces_only

    void _cdecl MyCPPFunction(char ** strName)
    {
        //Initialize COM
        HRESULT hr = CoInitialize(NULL);

        //create COM interface pointer
        MyNamespace::MyInterfacePtr myPtr;

        //create instance of COM class using the interface pointer
        HRESULT hr2 = myPtr.CreateInstance(MyNamespace::CLSID_MyClass);

       //create variable to hold output from COM.
       BSTR output;

       //call the COM function
       myPtr->MyFunction(_bstr_t(strName[0]), &output);

       //convert the returned BSTR from .net into char*
       int length = (int) SysStringLen(output);
       char *tempBuffer;
       tempBuffer = (char *) malloc(1 + length);
       WideCharToMultibyte(CP_ACP, 0, output, -1, tempBuffer, length, NULL, NULL);
       tempBuffer[length] = '\0';

       //release interface
       myPtr->Release();

       //uninitialize COM
       if(hr == S_OK)
         CoUninitialize();

       //set output in input for returning to R (this is weird but the only way I could make it work)
       strName[0] = tempBuffer;
    }
Run Code Online (Sandbox Code Playgroud)

现在编译你的项目,你将得到一个C++ DLL.我们差不多了!不要放弃:) 现在,您有一个C#DLL公开为COM对象和一个可以调用此COM对象的C++ DLL.最后一步是从R调用C++函数.这是执行该操作的R代码

#load C++ DLL
dyn.load("path_to_C++_DLL")

#call function in C++ DLL and pass in a test name.
# The C++ DLL will in turn call the C# function
output <- .C("MyCPPFunction", as.character("Peter"))

#print output
print(output)
Run Code Online (Sandbox Code Playgroud)

你应该在R控制台中看到C#中显示的"Hello Peter"!需要注意的一点非常重要.

总是,使用"任何CPU"选项编译COM DLL.始终编​​译C++ DLL以匹配您的R安装!例如,如果安装了32位R,请确保将C++ DLL编译为32位DLL.如果您安装了64位R并想要使用它,那么请确保将C++ DLL编译为64位DLL.祝你好运!


Fra*_* P. 0

http://www.codeproject.com/Articles/25819/The-R-Statistical-Language-and-C-NET-Foundations

看看这样的东西。现在我对 C# 不太了解,所以如果我说任何不可能的事情,请不要伤害我:

尝试将要优化的函数保存为 C# 中的字符,并使用此 StatConnector 库将其发送到 R(我对此的经验有限。)假设您在 R 中将方程保存为“z”,然后您可以使用“get(z)”作为变量之一来调用 R 脚本。