我想知道是否可以从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对象公开.您可以通过以下两种方式之一完成此操作
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.祝你好运!
http://www.codeproject.com/Articles/25819/The-R-Statistical-Language-and-C-NET-Foundations
看看这样的东西。现在我对 C# 不太了解,所以如果我说任何不可能的事情,请不要伤害我:
尝试将要优化的函数保存为 C# 中的字符,并使用此 StatConnector 库将其发送到 R(我对此的经验有限。)假设您在 R 中将方程保存为“z”,然后您可以使用“get(z)”作为变量之一来调用 R 脚本。